Changeset 79ae36dd in mainline for uspace/lib/c


Ignore:
Timestamp:
2011-06-08T19:01:55Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eff68e
Parents:
764d71e
Message:

new async framework with integrated exchange tracking

  • strict isolation between low-level IPC and high-level async framework with integrated exchange tracking
    • each IPC connection is represented by an async_sess_t structure
    • each IPC exchange is represented by an async_exch_t structure
    • exchange management is either based on atomic messages (EXCHANGE_ATOMIC), locking (EXCHANGE_SERIALIZE) or connection cloning (EXCHANGE_CLONE)
  • async_obsolete: temporary compatibility layer to keep old async clients working (several pieces of code are currently broken, but only non-essential functionality)
  • IPC_M_PHONE_HANGUP is now method no. 0 (for elegant boolean evaluation)
  • IPC_M_DEBUG_ALL has been renamed to IPC_M_DEBUG
  • IPC_M_PING has been removed (VFS protocol now has VFS_IN_PING)
  • console routines in libc have been rewritten for better abstraction
  • additional use for libc-private header files (FILE structure opaque to the client)
  • various cstyle changes (typos, indentation, missing externs in header files, improved comments, etc.)
Location:
uspace/lib/c
Files:
11 added
1 deleted
36 edited
3 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r764d71e r79ae36dd  
    6868        generic/clipboard.c \
    6969        generic/devmap.c \
     70        generic/devmap_obsolete.c \
    7071        generic/devman.c \
     72        generic/devman_obsolete.c \
    7173        generic/device/hw_res.c \
    7274        generic/device/char_dev.c \
     
    9698        generic/io/console.c \
    9799        generic/io/screenbuffer.c \
    98         generic/ipc/ns.c \
    99100        generic/malloc.c \
    100101        generic/sysinfo.c \
    101102        generic/ipc.c \
     103        generic/ns.c \
     104        generic/ns_obsolete.c \
    102105        generic/async.c \
    103         generic/async_sess.c \
     106        generic/async_obsolete.c \
    104107        generic/loader.c \
    105108        generic/getopt.c \
     
    129132        generic/assert.c
    130133
    131 ifeq ($(CONFIG_RTLD), y)
     134ifeq ($(CONFIG_RTLD),y)
    132135        GENERIC_SOURCES += \
    133136                generic/dlfcn.c \
  • uspace/lib/c/generic/adt/measured_strings.c

    r764d71e r79ae36dd  
    4242#include <errno.h>
    4343#include <async.h>
     44#include <async_obsolete.h>
    4445
    4546/** Creates a new measured string bundled with a copy of the given string
     
    326327                return ENOMEM;
    327328
    328         rc = async_data_read_start(phone, lengths,
     329        rc = async_obsolete_data_read_start(phone, lengths,
    329330            sizeof(size_t) * (count + 1));
    330331        if (rc != EOK) {
     
    351352                (*strings)[index].length = lengths[index];
    352353                if (lengths[index] > 0) {
    353                         rc = async_data_read_start(phone, next, lengths[index]);
     354                        rc = async_obsolete_data_read_start(phone, next, lengths[index]);
    354355                        if (rc != EOK) {
    355356                                free(lengths);
     
    399400                return ENOMEM;
    400401
    401         rc = async_data_write_start(phone, lengths,
     402        rc = async_obsolete_data_write_start(phone, lengths,
    402403            sizeof(size_t) * (count + 1));
    403404        if (rc != EOK) {
     
    410411        for (index = 0; index < count; index++) {
    411412                if (strings[index].length > 0) {
    412                         rc = async_data_write_start(phone, strings[index].value,
     413                        rc = async_obsolete_data_write_start(phone, strings[index].value,
    413414                            strings[index].length);
    414415                        if (rc != EOK)
  • uspace/lib/c/generic/async.c

    r764d71e r79ae36dd  
    4040 * programming.
    4141 *
    42  * You should be able to write very simple multithreaded programs, the async
    43  * framework will automatically take care of most synchronization problems.
     42 * You should be able to write very simple multithreaded programs. The async
     43 * framework will automatically take care of most of the synchronization
     44 * problems.
    4445 *
    4546 * Example of use (pseudo C):
     
    5354 *   int fibril1(void *arg)
    5455 *   {
    55  *     conn = async_connect_me_to();
    56  *     c1 = async_send(conn);
    57  *     c2 = async_send(conn);
     56 *     conn = async_connect_me_to(...);
     57 *
     58 *     exch = async_exchange_begin(conn);
     59 *     c1 = async_send(exch);
     60 *     async_exchange_end(exch);
     61 *
     62 *     exch = async_exchange_begin(conn);
     63 *     c2 = async_send(exch);
     64 *     async_exchange_end(exch);
     65 *
    5866 *     async_wait_for(c1);
    5967 *     async_wait_for(c2);
     
    94102#include <futex.h>
    95103#include <fibril.h>
    96 #include <stdio.h>
    97104#include <adt/hash_table.h>
    98105#include <adt/list.h>
     
    102109#include <arch/barrier.h>
    103110#include <bool.h>
     111#include <malloc.h>
     112#include <mem.h>
    104113#include <stdlib.h>
    105 #include <malloc.h>
    106114#include "private/async.h"
    107115
     116#define CLIENT_HASH_TABLE_BUCKETS  32
     117#define CONN_HASH_TABLE_BUCKETS    32
     118
     119/** Async framework global futex */
    108120atomic_t async_futex = FUTEX_INITIALIZER;
    109121
     
    111123atomic_t threads_in_ipc_wait = { 0 };
    112124
    113 typedef struct {
    114         awaiter_t wdata;
    115        
    116         /** If reply was received. */
    117         bool done;
    118        
    119         /** Pointer to where the answer data is stored. */
    120         ipc_call_t *dataptr;
    121        
    122         sysarg_t retval;
    123 } amsg_t;
    124 
    125 /**
    126  * Structures of this type are used to group information about
    127  * a call and about a message queue link.
    128  */
     125/** Naming service session */
     126async_sess_t *session_ns;
     127
     128/** Call data */
    129129typedef struct {
    130130        link_t link;
     131       
    131132        ipc_callid_t callid;
    132133        ipc_call_t call;
    133134} msg_t;
    134135
     136/* Client connection data */
    135137typedef struct {
     138        link_t link;
     139       
    136140        sysarg_t in_task_hash;
    137         link_t link;
    138         int refcnt;
     141        atomic_t refcnt;
    139142        void *data;
    140143} client_t;
    141144
     145/* Server connection data */
    142146typedef struct {
    143147        awaiter_t wdata;
     
    148152        /** Incoming client task hash. */
    149153        sysarg_t in_task_hash;
     154       
    150155        /** Incoming phone hash. */
    151156        sysarg_t in_phone_hash;
     
    170175
    171176/** Identifier of the incoming connection handled by the current fibril. */
    172 static fibril_local connection_t *FIBRIL_connection;
     177static fibril_local connection_t *fibril_connection;
    173178
    174179static void *default_client_data_constructor(void)
     
    196201}
    197202
    198 void *async_client_data_get(void)
    199 {
    200         assert(FIBRIL_connection);
    201         return FIBRIL_connection->client->data;
     203void *async_get_client_data(void)
     204{
     205        assert(fibril_connection);
     206        return fibril_connection->client->data;
    202207}
    203208
     
    215220}
    216221
    217 /**
    218  * Pointer to a fibril function that will be used to handle connections.
    219  */
    220 static async_client_conn_t client_connection = default_client_connection;
    221 
    222222/** Default fibril function that gets called to handle interrupt notifications.
    223223 *
     
    232232}
    233233
    234 /**
    235  * Pointer to a fibril function that will be used to handle interrupt
    236  * notifications.
    237  */
     234static async_client_conn_t client_connection = default_client_connection;
    238235static async_client_conn_t interrupt_received = default_interrupt_received;
     236
     237/** Setter for client_connection function pointer.
     238 *
     239 * @param conn Function that will implement a new connection fibril.
     240 *
     241 */
     242void async_set_client_connection(async_client_conn_t conn)
     243{
     244        client_connection = conn;
     245}
     246
     247/** Setter for interrupt_received function pointer.
     248 *
     249 * @param intr Function that will implement a new interrupt
     250 *             notification fibril.
     251 */
     252void async_set_interrupt_received(async_client_conn_t intr)
     253{
     254        interrupt_received = intr;
     255}
     256
     257/** Mutex protecting inactive_exch_list and avail_phone_cv.
     258 *
     259 */
     260static FIBRIL_MUTEX_INITIALIZE(async_sess_mutex);
     261
     262/** List of all currently inactive exchanges.
     263 *
     264 */
     265static LIST_INITIALIZE(inactive_exch_list);
     266
     267/** Condition variable to wait for a phone to become available.
     268 *
     269 */
     270static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
    239271
    240272static hash_table_t client_hash_table;
     
    242274static LIST_INITIALIZE(timeout_list);
    243275
    244 #define CLIENT_HASH_TABLE_BUCKETS  32
    245 #define CONN_HASH_TABLE_BUCKETS    32
    246 
    247276static hash_index_t client_hash(unsigned long key[])
    248277{
    249278        assert(key);
     279       
    250280        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
    251281}
     
    253283static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
    254284{
     285        assert(key);
     286        assert(item);
     287       
    255288        client_t *client = hash_table_get_instance(item, client_t, link);
    256289        return (key[0] == client->in_task_hash);
     
    278311{
    279312        assert(key);
     313       
    280314        return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
    281315}
     
    292326static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    293327{
     328        assert(key);
     329        assert(item);
     330       
    294331        connection_t *conn = hash_table_get_instance(item, connection_t, link);
    295332        return (key[0] == conn->in_phone_hash);
     
    314351void async_insert_timeout(awaiter_t *wd)
    315352{
     353        assert(wd);
     354       
    316355        wd->to_event.occurred = false;
    317356        wd->to_event.inlist = true;
     
    346385static bool route_call(ipc_callid_t callid, ipc_call_t *call)
    347386{
     387        assert(call);
     388       
    348389        futex_down(&async_futex);
    349390       
     
    400441static int notification_fibril(void *arg)
    401442{
     443        assert(arg);
     444       
    402445        msg_t *msg = (msg_t *) arg;
    403446        interrupt_received(msg->callid, &msg->call);
     
    420463static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
    421464{
     465        assert(call);
     466       
    422467        futex_down(&async_futex);
    423468       
     
    458503ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
    459504{
    460         assert(FIBRIL_connection);
     505        assert(call);
     506        assert(fibril_connection);
    461507       
    462508        /* Why doing this?
    463          * GCC 4.1.0 coughs on FIBRIL_connection-> dereference.
     509         * GCC 4.1.0 coughs on fibril_connection-> dereference.
    464510         * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
    465511         *           I would never expect to find so many errors in
    466512         *           a compiler.
    467513         */
    468         connection_t *conn = FIBRIL_connection;
     514        connection_t *conn = fibril_connection;
    469515       
    470516        futex_down(&async_futex);
     
    541587static int connection_fibril(void *arg)
    542588{
     589        assert(arg);
     590       
    543591        /*
    544592         * Setup fibril-local connection pointer.
    545593         */
    546         FIBRIL_connection = (connection_t *) arg;
     594        fibril_connection = (connection_t *) arg;
    547595       
    548596        futex_down(&async_futex);
     
    554602         */
    555603       
    556         unsigned long key = FIBRIL_connection->in_task_hash;
     604        unsigned long key = fibril_connection->in_task_hash;
    557605        link_t *lnk = hash_table_find(&client_hash_table, &key);
    558606       
     
    561609        if (lnk) {
    562610                client = hash_table_get_instance(lnk, client_t, link);
    563                 client->refcnt++;
     611                atomic_inc(&client->refcnt);
    564612        } else {
    565613                client = malloc(sizeof(client_t));
    566614                if (!client) {
    567                         ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
     615                        ipc_answer_0(fibril_connection->callid, ENOMEM);
    568616                        futex_up(&async_futex);
    569617                        return 0;
    570618                }
    571619               
    572                 client->in_task_hash = FIBRIL_connection->in_task_hash;
    573                
    574                 async_serialize_start();
     620                client->in_task_hash = fibril_connection->in_task_hash;
    575621                client->data = async_client_data_create();
    576                 async_serialize_end();
    577                
    578                 client->refcnt = 1;
     622               
     623                atomic_set(&client->refcnt, 1);
    579624                hash_table_insert(&client_hash_table, &key, &client->link);
    580625        }
     
    582627        futex_up(&async_futex);
    583628       
    584         FIBRIL_connection->client = client;
     629        fibril_connection->client = client;
    585630       
    586631        /*
    587632         * Call the connection handler function.
    588633         */
    589         FIBRIL_connection->cfibril(FIBRIL_connection->callid,
    590             &FIBRIL_connection->call);
     634        fibril_connection->cfibril(fibril_connection->callid,
     635            &fibril_connection->call);
    591636       
    592637        /*
     
    597642        futex_down(&async_futex);
    598643       
    599         if (--client->refcnt == 0) {
     644        if (atomic_predec(&client->refcnt) == 0) {
    600645                hash_table_remove(&client_hash_table, &key, 1);
    601646                destroy = true;
     
    616661         */
    617662        futex_down(&async_futex);
    618         key = FIBRIL_connection->in_phone_hash;
     663        key = fibril_connection->in_phone_hash;
    619664        hash_table_remove(&conn_hash_table, &key, 1);
    620665        futex_up(&async_futex);
     
    623668         * Answer all remaining messages with EHANGUP.
    624669         */
    625         while (!list_empty(&FIBRIL_connection->msg_queue)) {
     670        while (!list_empty(&fibril_connection->msg_queue)) {
    626671                msg_t *msg =
    627                     list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
     672                    list_get_instance(fibril_connection->msg_queue.next, msg_t,
    628673                    link);
    629674               
     
    637682         * i.e. IPC_M_PHONE_HUNGUP.
    638683         */
    639         if (FIBRIL_connection->close_callid)
    640                 ipc_answer_0(FIBRIL_connection->close_callid, EOK);
    641        
    642         free(FIBRIL_connection);
     684        if (fibril_connection->close_callid)
     685                ipc_answer_0(fibril_connection->close_callid, EOK);
     686       
     687        free(fibril_connection);
    643688        return 0;
    644689}
     
    646691/** Create a new fibril for a new connection.
    647692 *
    648  * Create new fibril for connection, fill in connection structures and inserts
     693 * Create new fibril for connection, fill in connection structures and insert
    649694 * it into the hash table, so that later we can easily do routing of messages to
    650695 * particular fibrils.
     
    665710fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
    666711    ipc_callid_t callid, ipc_call_t *call,
    667     void (*cfibril)(ipc_callid_t, ipc_call_t *))
     712    async_client_conn_t cfibril)
    668713{
    669714        connection_t *conn = malloc(sizeof(*conn));
     
    721766static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    722767{
     768        assert(call);
     769       
    723770        /* Unrouted call - take some default action */
    724771        if ((callid & IPC_CALLID_NOTIFICATION)) {
     
    878925void __async_init(void)
    879926{
    880         if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
    881             &client_hash_table_ops))
     927        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
     928            1, &client_hash_table_ops))
    882929                abort();
    883930       
    884         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
    885             &conn_hash_table_ops))
     931        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS,
     932            1, &conn_hash_table_ops))
    886933                abort();
     934       
     935        session_ns = (async_sess_t *) malloc(sizeof(async_sess_t));
     936        if (session_ns == NULL)
     937                abort();
     938       
     939        session_ns->mgmt = EXCHANGE_ATOMIC;
     940        session_ns->phone = PHONE_NS;
     941        session_ns->arg1 = 0;
     942        session_ns->arg2 = 0;
     943        session_ns->arg3 = 0;
     944       
     945        list_initialize(&session_ns->exch_list);
     946        fibril_mutex_initialize(&session_ns->mutex);
     947        atomic_set(&session_ns->refcnt, 0);
    887948}
    888949
     
    899960 *
    900961 */
    901 static void reply_received(void *arg, int retval, ipc_call_t *data)
    902 {
     962void reply_received(void *arg, int retval, ipc_call_t *data)
     963{
     964        assert(arg);
     965       
    903966        futex_down(&async_futex);
    904967       
     
    930993 * completion.
    931994 *
    932  * @param phoneid Handle of the phone that will be used for the send.
    933  * @param method  Service-defined method.
     995 * @param exch    Exchange for sending the message.
     996 * @param imethod Service-defined interface and method.
    934997 * @param arg1    Service-defined payload argument.
    935998 * @param arg2    Service-defined payload argument.
     
    9421005 *
    9431006 */
    944 aid_t async_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1007aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    9451008    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    9461009{
     1010        if (exch == NULL)
     1011                return 0;
     1012       
    9471013        amsg_t *msg = malloc(sizeof(amsg_t));
    948        
    949         if (!msg)
     1014        if (msg == NULL)
    9501015                return 0;
    9511016       
     
    9611026        msg->wdata.active = true;
    9621027       
    963         ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
     1028        ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg,
    9641029            reply_received, true);
    9651030       
     
    9721037 * completion.
    9731038 *
    974  * @param phoneid Handle of the phone that will be used for the send.
    975  * @param method  Service-defined method.
     1039 * @param exch    Exchange for sending the message.
     1040 * @param imethod Service-defined interface and method.
    9761041 * @param arg1    Service-defined payload argument.
    9771042 * @param arg2    Service-defined payload argument.
     
    9851050 *
    9861051 */
    987 aid_t async_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
     1052aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    9881053    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    9891054    ipc_call_t *dataptr)
    9901055{
     1056        if (exch == NULL)
     1057                return 0;
     1058       
    9911059        amsg_t *msg = malloc(sizeof(amsg_t));
    9921060       
    993         if (!msg)
     1061        if (msg == NULL)
    9941062                return 0;
    9951063       
     
    10051073        msg->wdata.active = true;
    10061074       
    1007         ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
    1008             reply_received, true);
     1075        ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5,
     1076            msg, reply_received, true);
    10091077       
    10101078        return (aid_t) msg;
     
    10201088void async_wait_for(aid_t amsgid, sysarg_t *retval)
    10211089{
     1090        assert(amsgid);
     1091       
    10221092        amsg_t *msg = (amsg_t *) amsgid;
    10231093       
     
    10561126int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout)
    10571127{
     1128        assert(amsgid);
     1129       
    10581130        amsg_t *msg = (amsg_t *) amsgid;
    10591131       
     
    11241196}
    11251197
    1126 /** Setter for client_connection function pointer.
    1127  *
    1128  * @param conn Function that will implement a new connection fibril.
    1129  *
    1130  */
    1131 void async_set_client_connection(async_client_conn_t conn)
    1132 {
    1133         client_connection = conn;
    1134 }
    1135 
    1136 /** Setter for interrupt_received function pointer.
    1137  *
    1138  * @param intr Function that will implement a new interrupt
    1139  *             notification fibril.
    1140  */
    1141 void async_set_interrupt_received(async_client_conn_t intr)
    1142 {
    1143         interrupt_received = intr;
    1144 }
    1145 
    11461198/** Pseudo-synchronous message sending - fast version.
    11471199 *
     
    11511203 * transferring more arguments, see the slower async_req_slow().
    11521204 *
    1153  * @param phoneid Hash of the phone through which to make the call.
    1154  * @param method  Method of the call.
     1205 * @param exch    Exchange for sending the message.
     1206 * @param imethod Interface and method of the call.
    11551207 * @param arg1    Service-defined payload argument.
    11561208 * @param arg2    Service-defined payload argument.
     
    11661218 *
    11671219 */
    1168 sysarg_t async_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     1220sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    11691221    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
    11701222    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    11711223{
     1224        if (exch == NULL)
     1225                return ENOENT;
     1226       
    11721227        ipc_call_t result;
    1173         aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4,
     1228        aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
    11741229            &result);
    11751230       
    11761231        sysarg_t rc;
    1177         async_wait_for(eid, &rc);
     1232        async_wait_for(aid, &rc);
    11781233       
    11791234        if (r1)
     
    11991254 * Send message asynchronously and return only after the reply arrives.
    12001255 *
    1201  * @param phoneid Hash of the phone through which to make the call.
    1202  * @param method  Method of the call.
     1256 * @param exch    Exchange for sending the message.
     1257 * @param imethod Interface and method of the call.
    12031258 * @param arg1    Service-defined payload argument.
    12041259 * @param arg2    Service-defined payload argument.
     
    12151270 *
    12161271 */
    1217 sysarg_t async_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
     1272sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
    12181273    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
    12191274    sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
    12201275{
     1276        if (exch == NULL)
     1277                return ENOENT;
     1278       
    12211279        ipc_call_t result;
    1222         aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5,
     1280        aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5,
    12231281            &result);
    12241282       
    12251283        sysarg_t rc;
    1226         async_wait_for(eid, &rc);
     1284        async_wait_for(aid, &rc);
    12271285       
    12281286        if (r1)
     
    12441302}
    12451303
    1246 void async_msg_0(int phone, sysarg_t imethod)
    1247 {
    1248         ipc_call_async_0(phone, imethod, NULL, NULL, true);
    1249 }
    1250 
    1251 void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
    1252 {
    1253         ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
    1254 }
    1255 
    1256 void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
    1257 {
    1258         ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
    1259 }
    1260 
    1261 void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1262     sysarg_t arg3)
    1263 {
    1264         ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
    1265 }
    1266 
    1267 void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1268     sysarg_t arg3, sysarg_t arg4)
    1269 {
    1270         ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
    1271             true);
    1272 }
    1273 
    1274 void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    1275     sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
    1276 {
    1277         ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
    1278             NULL, true);
     1304void async_msg_0(async_exch_t *exch, sysarg_t imethod)
     1305{
     1306        if (exch != NULL)
     1307                ipc_call_async_0(exch->phone, imethod, NULL, NULL, true);
     1308}
     1309
     1310void async_msg_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1)
     1311{
     1312        if (exch != NULL)
     1313                ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true);
     1314}
     1315
     1316void async_msg_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1317    sysarg_t arg2)
     1318{
     1319        if (exch != NULL)
     1320                ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL,
     1321                    true);
     1322}
     1323
     1324void async_msg_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1325    sysarg_t arg2, sysarg_t arg3)
     1326{
     1327        if (exch != NULL)
     1328                ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL,
     1329                    NULL, true);
     1330}
     1331
     1332void async_msg_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1333    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     1334{
     1335        if (exch != NULL)
     1336                ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4,
     1337                    NULL, NULL, true);
     1338}
     1339
     1340void async_msg_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     1341    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1342{
     1343        if (exch != NULL)
     1344                ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4,
     1345                    arg5, NULL, NULL, true);
    12791346}
    12801347
     
    13131380}
    13141381
    1315 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    1316     sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    1317 {
    1318         return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
    1319 }
    1320 
    1321 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    1322     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    1323     unsigned int mode)
    1324 {
    1325         return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
    1326             arg5, mode);
     1382int async_forward_fast(ipc_callid_t callid, async_exch_t *exch,
     1383    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     1384{
     1385        if (exch == NULL)
     1386                return ENOENT;
     1387       
     1388        return ipc_forward_fast(callid, exch->phone, imethod, arg1, arg2, mode);
     1389}
     1390
     1391int async_forward_slow(ipc_callid_t callid, async_exch_t *exch,
     1392    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     1393    sysarg_t arg4, sysarg_t arg5, unsigned int mode)
     1394{
     1395        if (exch == NULL)
     1396                return ENOENT;
     1397       
     1398        return ipc_forward_slow(callid, exch->phone, imethod, arg1, arg2, arg3,
     1399            arg4, arg5, mode);
    13271400}
    13281401
     
    13311404 * Ask through phone for a new connection to some service.
    13321405 *
    1333  * @param phone           Phone handle used for contacting the other side.
     1406 * @param exch            Exchange for sending the message.
    13341407 * @param arg1            User defined argument.
    13351408 * @param arg2            User defined argument.
     
    13371410 * @param client_receiver Connection handing routine.
    13381411 *
    1339  * @return New phone handle on success or a negative error code.
    1340  *
    1341  */
    1342 int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
     1412 * @return Zero on success or a negative error code.
     1413 *
     1414 */
     1415int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
    13431416    sysarg_t arg3, async_client_conn_t client_receiver)
    13441417{
     1418        if (exch == NULL)
     1419                return ENOENT;
     1420       
    13451421        sysarg_t task_hash;
    13461422        sysarg_t phone_hash;
    1347         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1423        int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    13481424            NULL, NULL, NULL, &task_hash, &phone_hash);
    13491425        if (rc != EOK)
     
    13571433}
    13581434
    1359 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1360  *
    1361  * Ask through phone for a new connection to some service.
    1362  *
    1363  * @param phone Phone handle used for contacting the other side.
    1364  * @param arg1  User defined argument.
    1365  * @param arg2  User defined argument.
    1366  * @param arg3  User defined argument.
    1367  *
    1368  * @return New phone handle on success or a negative error code.
    1369  *
    1370  */
    1371 int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
    1372     sysarg_t arg3)
    1373 {
    1374         sysarg_t newphid;
    1375         int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    1376             NULL, NULL, NULL, NULL, &newphid);
     1435/** Wrapper for making IPC_M_CONNECT_ME calls using the async framework.
     1436 *
     1437 * Ask through for a cloned connection to some service.
     1438 *
     1439 * @param mgmt Exchange management style.
     1440 * @param exch Exchange for sending the message.
     1441 *
     1442 * @return New session on success or NULL on error.
     1443 *
     1444 */
     1445async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch)
     1446{
     1447        if (exch == NULL) {
     1448                errno = ENOENT;
     1449                return NULL;
     1450        }
     1451       
     1452        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1453        if (sess == NULL) {
     1454                errno = ENOMEM;
     1455                return NULL;
     1456        }
     1457       
     1458        ipc_call_t result;
     1459       
     1460        amsg_t *msg = malloc(sizeof(amsg_t));
     1461        if (msg == NULL) {
     1462                free(sess);
     1463                errno = ENOMEM;
     1464                return NULL;
     1465        }
     1466       
     1467        msg->done = false;
     1468        msg->dataptr = &result;
     1469       
     1470        msg->wdata.to_event.inlist = false;
     1471       
     1472        /*
     1473         * We may sleep in the next method,
     1474         * but it will use its own means
     1475         */
     1476        msg->wdata.active = true;
     1477       
     1478        ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg,
     1479            reply_received, true);
     1480       
     1481        sysarg_t rc;
     1482        async_wait_for((aid_t) msg, &rc);
     1483       
     1484        if (rc != EOK) {
     1485                errno = rc;
     1486                free(sess);
     1487                return NULL;
     1488        }
     1489       
     1490        int phone = (int) IPC_GET_ARG5(result);
     1491       
     1492        if (phone < 0) {
     1493                errno = phone;
     1494                free(sess);
     1495                return NULL;
     1496        }
     1497       
     1498        sess->mgmt = mgmt;
     1499        sess->phone = phone;
     1500        sess->arg1 = 0;
     1501        sess->arg2 = 0;
     1502        sess->arg3 = 0;
     1503       
     1504        list_initialize(&sess->exch_list);
     1505        fibril_mutex_initialize(&sess->mutex);
     1506        atomic_set(&sess->refcnt, 0);
     1507       
     1508        return sess;
     1509}
     1510
     1511static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2,
     1512    sysarg_t arg3, sysarg_t arg4)
     1513{
     1514        ipc_call_t result;
     1515       
     1516        amsg_t *msg = malloc(sizeof(amsg_t));
     1517        if (msg == NULL)
     1518                return ENOENT;
     1519       
     1520        msg->done = false;
     1521        msg->dataptr = &result;
     1522       
     1523        msg->wdata.to_event.inlist = false;
     1524       
     1525        /*
     1526         * We may sleep in the next method,
     1527         * but it will use its own means
     1528         */
     1529        msg->wdata.active = true;
     1530       
     1531        ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4,
     1532            msg, reply_received, true);
     1533       
     1534        sysarg_t rc;
     1535        async_wait_for((aid_t) msg, &rc);
    13771536       
    13781537        if (rc != EOK)
    13791538                return rc;
    13801539       
    1381         return newphid;
     1540        return (int) IPC_GET_ARG5(result);
     1541}
     1542
     1543/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
     1544 *
     1545 * Ask through for a new connection to some service.
     1546 *
     1547 * @param mgmt Exchange management style.
     1548 * @param exch Exchange for sending the message.
     1549 * @param arg1 User defined argument.
     1550 * @param arg2 User defined argument.
     1551 * @param arg3 User defined argument.
     1552 *
     1553 * @return New session on success or NULL on error.
     1554 *
     1555 */
     1556async_sess_t *async_connect_me_to(exch_mgmt_t mgmt, async_exch_t *exch,
     1557    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     1558{
     1559        if (exch == NULL) {
     1560                errno = ENOENT;
     1561                return NULL;
     1562        }
     1563       
     1564        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1565        if (sess == NULL) {
     1566                errno = ENOMEM;
     1567                return NULL;
     1568        }
     1569       
     1570        int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
     1571            0);
     1572       
     1573        if (phone < 0) {
     1574                errno = phone;
     1575                free(sess);
     1576                return NULL;
     1577        }
     1578       
     1579        sess->mgmt = mgmt;
     1580        sess->phone = phone;
     1581        sess->arg1 = arg1;
     1582        sess->arg2 = arg2;
     1583        sess->arg3 = arg3;
     1584       
     1585        list_initialize(&sess->exch_list);
     1586        fibril_mutex_initialize(&sess->mutex);
     1587        atomic_set(&sess->refcnt, 0);
     1588       
     1589        return sess;
    13821590}
    13831591
     
    13871595 * success.
    13881596 *
    1389  * @param phoneid Phone handle used for contacting the other side.
    1390  * @param arg1    User defined argument.
    1391  * @param arg2    User defined argument.
    1392  * @param arg3    User defined argument.
    1393  *
    1394  * @return New phone handle on success or a negative error code.
    1395  *
    1396  */
    1397 int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
    1398     sysarg_t arg3)
    1399 {
    1400         sysarg_t newphid;
    1401         int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    1402             IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    1403        
    1404         if (rc != EOK)
    1405                 return rc;
    1406        
    1407         return newphid;
     1597 * @param mgmt Exchange management style.
     1598 * @param exch Exchange for sending the message.
     1599 * @param arg1 User defined argument.
     1600 * @param arg2 User defined argument.
     1601 * @param arg3 User defined argument.
     1602 *
     1603 * @return New session on success or NULL on error.
     1604 *
     1605 */
     1606async_sess_t *async_connect_me_to_blocking(exch_mgmt_t mgmt, async_exch_t *exch,
     1607    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
     1608{
     1609        if (exch == NULL) {
     1610                errno = ENOENT;
     1611                return NULL;
     1612        }
     1613       
     1614        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1615        if (sess == NULL) {
     1616                errno = ENOMEM;
     1617                return NULL;
     1618        }
     1619       
     1620        int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
     1621            IPC_FLAG_BLOCKING);
     1622       
     1623        if (phone < 0) {
     1624                errno = phone;
     1625                free(sess);
     1626                return NULL;
     1627        }
     1628       
     1629        sess->mgmt = mgmt;
     1630        sess->phone = phone;
     1631        sess->arg1 = arg1;
     1632        sess->arg2 = arg2;
     1633        sess->arg3 = arg3;
     1634       
     1635        list_initialize(&sess->exch_list);
     1636        fibril_mutex_initialize(&sess->mutex);
     1637        atomic_set(&sess->refcnt, 0);
     1638       
     1639        return sess;
    14081640}
    14091641
     
    14111643 *
    14121644 */
    1413 int async_connect_kbox(task_id_t id)
    1414 {
    1415         return ipc_connect_kbox(id);
     1645async_sess_t *async_connect_kbox(task_id_t id)
     1646{
     1647        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     1648        if (sess == NULL) {
     1649                errno = ENOMEM;
     1650                return NULL;
     1651        }
     1652       
     1653        int phone = ipc_connect_kbox(id);
     1654        if (phone < 0) {
     1655                errno = phone;
     1656                free(sess);
     1657                return NULL;
     1658        }
     1659       
     1660        sess->mgmt = EXCHANGE_ATOMIC;
     1661        sess->phone = phone;
     1662        sess->arg1 = 0;
     1663        sess->arg2 = 0;
     1664        sess->arg3 = 0;
     1665       
     1666        list_initialize(&sess->exch_list);
     1667        fibril_mutex_initialize(&sess->mutex);
     1668        atomic_set(&sess->refcnt, 0);
     1669       
     1670        return sess;
     1671}
     1672
     1673static int async_hangup_internal(int phone)
     1674{
     1675        return ipc_hangup(phone);
    14161676}
    14171677
    14181678/** Wrapper for ipc_hangup.
    14191679 *
    1420  * @param phone Phone handle to hung up.
     1680 * @param sess Session to hung up.
    14211681 *
    14221682 * @return Zero on success or a negative error code.
    14231683 *
    14241684 */
    1425 int async_hangup(int phone)
    1426 {
    1427         return ipc_hangup(phone);
     1685int async_hangup(async_sess_t *sess)
     1686{
     1687        assert(sess);
     1688       
     1689        if (atomic_get(&sess->refcnt) > 0)
     1690                return EBUSY;
     1691       
     1692        int rc = async_hangup_internal(sess->phone);
     1693        if (rc == EOK)
     1694                free(sess);
     1695       
     1696        return rc;
    14281697}
    14291698
     
    14341703}
    14351704
     1705/** Start new exchange in a session.
     1706 *
     1707 * @param session Session.
     1708 *
     1709 * @return New exchange or NULL on error.
     1710 *
     1711 */
     1712async_exch_t *async_exchange_begin(async_sess_t *sess)
     1713{
     1714        if (sess == NULL)
     1715                return NULL;
     1716       
     1717        async_exch_t *exch;
     1718       
     1719        fibril_mutex_lock(&async_sess_mutex);
     1720       
     1721        if (!list_empty(&sess->exch_list)) {
     1722                /*
     1723                 * There are inactive exchanges in the session.
     1724                 */
     1725                exch = (async_exch_t *)
     1726                    list_get_instance(sess->exch_list.next, async_exch_t, sess_link);
     1727                list_remove(&exch->sess_link);
     1728                list_remove(&exch->global_link);
     1729        } else {
     1730                /*
     1731                 * There are no available exchanges in the session.
     1732                 */
     1733               
     1734                if ((sess->mgmt == EXCHANGE_ATOMIC) ||
     1735                    (sess->mgmt == EXCHANGE_SERIALIZE)) {
     1736                        exch = (async_exch_t *) malloc(sizeof(async_exch_t));
     1737                        if (exch != NULL) {
     1738                                list_initialize(&exch->sess_link);
     1739                                list_initialize(&exch->global_link);
     1740                                exch->sess = sess;
     1741                                exch->phone = sess->phone;
     1742                        }
     1743                } else {  /* EXCHANGE_PARALLEL */
     1744                        /*
     1745                         * Make a one-time attempt to connect a new data phone.
     1746                         */
     1747                       
     1748                        int phone;
     1749                       
     1750retry:
     1751                        phone = async_connect_me_to_internal(sess->phone, sess->arg1,
     1752                            sess->arg2, sess->arg3, 0);
     1753                        if (phone >= 0) {
     1754                                exch = (async_exch_t *) malloc(sizeof(async_exch_t));
     1755                                if (exch != NULL) {
     1756                                        list_initialize(&exch->sess_link);
     1757                                        list_initialize(&exch->global_link);
     1758                                        exch->sess = sess;
     1759                                        exch->phone = phone;
     1760                                } else
     1761                                        async_hangup_internal(phone);
     1762                        } else if (!list_empty(&inactive_exch_list)) {
     1763                                /*
     1764                                 * We did not manage to connect a new phone. But we
     1765                                 * can try to close some of the currently inactive
     1766                                 * connections in other sessions and try again.
     1767                                 */
     1768                                exch = (async_exch_t *)
     1769                                    list_get_instance(inactive_exch_list.next, async_exch_t,
     1770                                    global_link);
     1771                                list_remove(&exch->sess_link);
     1772                                list_remove(&exch->global_link);
     1773                                async_hangup_internal(exch->phone);
     1774                                free(exch);
     1775                                goto retry;
     1776                        } else {
     1777                                /*
     1778                                 * Wait for a phone to become available.
     1779                                 */
     1780                                fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
     1781                                goto retry;
     1782                        }
     1783                }
     1784        }
     1785       
     1786        fibril_mutex_unlock(&async_sess_mutex);
     1787       
     1788        if (exch != NULL) {
     1789                atomic_inc(&sess->refcnt);
     1790               
     1791                if (sess->mgmt == EXCHANGE_SERIALIZE)
     1792                        fibril_mutex_lock(&sess->mutex);
     1793        }
     1794       
     1795        return exch;
     1796}
     1797
     1798/** Finish an exchange.
     1799 *
     1800 * @param exch Exchange to finish.
     1801 *
     1802 */
     1803void async_exchange_end(async_exch_t *exch)
     1804{
     1805        if (exch == NULL)
     1806                return;
     1807       
     1808        async_sess_t *sess = exch->sess;
     1809       
     1810        if (sess->mgmt == EXCHANGE_SERIALIZE)
     1811                fibril_mutex_unlock(&sess->mutex);
     1812       
     1813        fibril_mutex_lock(&async_sess_mutex);
     1814       
     1815        list_append(&exch->sess_link, &sess->exch_list);
     1816        list_append(&exch->global_link, &inactive_exch_list);
     1817        fibril_condvar_signal(&avail_phone_cv);
     1818       
     1819        fibril_mutex_unlock(&async_sess_mutex);
     1820}
     1821
    14361822/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
    14371823 *
    1438  * @param phoneid Phone that will be used to contact the receiving side.
    1439  * @param dst     Destination address space area base.
    1440  * @param size    Size of the destination address space area.
    1441  * @param arg     User defined argument.
    1442  * @param flags   Storage for the received flags. Can be NULL.
     1824 * @param exch  Exchange for sending the message.
     1825 * @param dst   Destination address space area base.
     1826 * @param size  Size of the destination address space area.
     1827 * @param arg   User defined argument.
     1828 * @param flags Storage for the received flags. Can be NULL.
    14431829 *
    14441830 * @return Zero on success or a negative error code from errno.h.
    14451831 *
    14461832 */
    1447 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    1448     unsigned int *flags)
    1449 {
     1833int async_share_in_start(async_exch_t *exch, void *dst, size_t size,
     1834    sysarg_t arg, unsigned int *flags)
     1835{
     1836        if (exch == NULL)
     1837                return ENOENT;
     1838       
    14501839        sysarg_t tmp_flags;
    1451         int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     1840        int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst,
    14521841            (sysarg_t) size, arg, NULL, &tmp_flags);
    14531842       
     
    15071896/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
    15081897 *
    1509  * @param phoneid Phone that will be used to contact the receiving side.
    1510  * @param src     Source address space area base address.
    1511  * @param flags   Flags to be used for sharing. Bits can be only cleared.
     1898 * @param exch  Exchange for sending the message.
     1899 * @param src   Source address space area base address.
     1900 * @param flags Flags to be used for sharing. Bits can be only cleared.
    15121901 *
    15131902 * @return Zero on success or a negative error code from errno.h.
    15141903 *
    15151904 */
    1516 int async_share_out_start(int phoneid, void *src, unsigned int flags)
    1517 {
    1518         return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     1905int async_share_out_start(async_exch_t *exch, void *src, unsigned int flags)
     1906{
     1907        if (exch == NULL)
     1908                return ENOENT;
     1909       
     1910        return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
    15191911            (sysarg_t) flags);
    15201912}
     
    15711963/** Start IPC_M_DATA_READ using the async framework.
    15721964 *
    1573  * @param phoneid Phone that will be used to contact the receiving side.
    1574  * @param dst Address of the beginning of the destination buffer.
    1575  * @param size Size of the destination buffer (in bytes).
     1965 * @param exch    Exchange for sending the message.
     1966 * @param dst     Address of the beginning of the destination buffer.
     1967 * @param size    Size of the destination buffer (in bytes).
    15761968 * @param dataptr Storage of call data (arg 2 holds actual data size).
     1969 *
    15771970 * @return Hash of the sent message or 0 on error.
    1578  */
    1579 aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)
    1580 {
    1581         return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
     1971 *
     1972 */
     1973aid_t async_data_read(async_exch_t *exch, void *dst, size_t size,
     1974    ipc_call_t *dataptr)
     1975{
     1976        return async_send_2(exch, IPC_M_DATA_READ, (sysarg_t) dst,
    15821977            (sysarg_t) size, dataptr);
    15831978}
     
    15851980/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15861981 *
    1587  * @param phoneid Phone that will be used to contact the receiving side.
    1588  * @param dst     Address of the beginning of the destination buffer.
    1589  * @param size    Size of the destination buffer.
    1590  * @param flags   Flags to control the data transfer.
     1982 * @param exch Exchange for sending the message.
     1983 * @param dst  Address of the beginning of the destination buffer.
     1984 * @param size Size of the destination buffer.
    15911985 *
    15921986 * @return Zero on success or a negative error code from errno.h.
    15931987 *
    15941988 */
    1595 int
    1596 async_data_read_start_generic(int phoneid, void *dst, size_t size, int flags)
    1597 {
    1598         return async_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
    1599             (sysarg_t) size, (sysarg_t) flags);
     1989int async_data_read_start(async_exch_t *exch, void *dst, size_t size)
     1990{
     1991        if (exch == NULL)
     1992                return ENOENT;
     1993       
     1994        return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst,
     1995            (sysarg_t) size);
    16001996}
    16011997
     
    16522048 *
    16532049 */
    1654 int async_data_read_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    1655     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    1656 {
     2050int async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
     2051    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     2052    ipc_call_t *dataptr)
     2053{
     2054        if (exch == NULL)
     2055                return ENOENT;
     2056       
    16572057        ipc_callid_t callid;
    16582058        if (!async_data_read_receive(&callid, NULL)) {
     
    16612061        }
    16622062       
    1663         aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     2063        aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
    16642064            dataptr);
    16652065        if (msg == 0) {
     
    16682068        }
    16692069       
    1670         int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     2070        int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
    16712071            IPC_FF_ROUTE_FROM_ME);
    16722072        if (retval != EOK) {
     
    16842084/** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
    16852085 *
    1686  * @param phoneid Phone that will be used to contact the receiving side.
    1687  * @param src     Address of the beginning of the source buffer.
    1688  * @param size    Size of the source buffer.
    1689  * @param flags   Flags to control the data transfer.
     2086 * @param exch Exchange for sending the message.
     2087 * @param src  Address of the beginning of the source buffer.
     2088 * @param size Size of the source buffer.
    16902089 *
    16912090 * @return Zero on success or a negative error code from errno.h.
    16922091 *
    16932092 */
    1694 int
    1695 async_data_write_start_generic(int phoneid, const void *src, size_t size,
    1696     int flags)
    1697 {
    1698         return async_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
    1699             (sysarg_t) size, (sysarg_t) flags);
     2093int async_data_write_start(async_exch_t *exch, const void *src, size_t size)
     2094{
     2095        if (exch == NULL)
     2096                return ENOENT;
     2097       
     2098        return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src,
     2099            (sysarg_t) size);
    17002100}
    17012101
     
    17732173    size_t *received)
    17742174{
     2175        assert(data);
     2176       
    17752177        ipc_callid_t callid;
    17762178        size_t size;
     
    18402242 *
    18412243 */
    1842 int async_data_write_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    1843     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    1844 {
     2244int async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod,
     2245    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     2246    ipc_call_t *dataptr)
     2247{
     2248        if (exch == NULL)
     2249                return ENOENT;
     2250       
    18452251        ipc_callid_t callid;
    18462252        if (!async_data_write_receive(&callid, NULL)) {
     
    18492255        }
    18502256       
    1851         aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     2257        aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
    18522258            dataptr);
    18532259        if (msg == 0) {
     
    18562262        }
    18572263       
    1858         int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     2264        int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
    18592265            IPC_FF_ROUTE_FROM_ME);
    18602266        if (retval != EOK) {
     
    18702276}
    18712277
     2278/** Wrapper for sending an exchange over different exchange for cloning
     2279 *
     2280 * @param exch       Exchange to be used for sending.
     2281 * @param clone_exch Exchange to be cloned.
     2282 *
     2283 */
     2284int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
     2285{
     2286        return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
     2287}
     2288
     2289/** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
     2290 *
     2291 * If the current call is IPC_M_CONNECTION_CLONE then a new
     2292 * async session is created for the accepted phone.
     2293 *
     2294 * @param mgmt Exchange management style.
     2295 *
     2296 * @return New async session or NULL on failure.
     2297 *
     2298 */
     2299async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
     2300{
     2301        /* Accept the phone */
     2302        ipc_call_t call;
     2303        ipc_callid_t callid = async_get_call(&call);
     2304        int phone = (int) IPC_GET_ARG1(call);
     2305       
     2306        if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
     2307            (phone < 0)) {
     2308                async_answer_0(callid, EINVAL);
     2309                return NULL;
     2310        }
     2311       
     2312        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2313        if (sess == NULL) {
     2314                async_answer_0(callid, ENOMEM);
     2315                return NULL;
     2316        }
     2317       
     2318        sess->mgmt = mgmt;
     2319        sess->phone = phone;
     2320        sess->arg1 = 0;
     2321        sess->arg2 = 0;
     2322        sess->arg3 = 0;
     2323       
     2324        list_initialize(&sess->exch_list);
     2325        fibril_mutex_initialize(&sess->mutex);
     2326        atomic_set(&sess->refcnt, 0);
     2327       
     2328        /* Acknowledge the cloned phone */
     2329        async_answer_0(callid, EOK);
     2330       
     2331        return sess;
     2332}
     2333
     2334/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
     2335 *
     2336 * If the current call is IPC_M_CONNECT_TO_ME then a new
     2337 * async session is created for the accepted phone.
     2338 *
     2339 * @param mgmt Exchange management style.
     2340 *
     2341 * @return New async session or NULL on failure.
     2342 *
     2343 */
     2344async_sess_t *async_callback_receive(exch_mgmt_t mgmt)
     2345{
     2346        /* Accept the phone */
     2347        ipc_call_t call;
     2348        ipc_callid_t callid = async_get_call(&call);
     2349        int phone = (int) IPC_GET_ARG5(call);
     2350       
     2351        if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) ||
     2352            (phone < 0)) {
     2353                async_answer_0(callid, EINVAL);
     2354                return NULL;
     2355        }
     2356       
     2357        async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
     2358        if (sess == NULL) {
     2359                async_answer_0(callid, ENOMEM);
     2360                return NULL;
     2361        }
     2362       
     2363        sess->mgmt = mgmt;
     2364        sess->phone = phone;
     2365        sess->arg1 = 0;
     2366        sess->arg2 = 0;
     2367        sess->arg3 = 0;
     2368       
     2369        list_initialize(&sess->exch_list);
     2370        fibril_mutex_initialize(&sess->mutex);
     2371        atomic_set(&sess->refcnt, 0);
     2372       
     2373        /* Acknowledge the connected phone */
     2374        async_answer_0(callid, EOK);
     2375       
     2376        return sess;
     2377}
     2378
    18722379/** @}
    18732380 */
  • uspace/lib/c/generic/clipboard.c

    r764d71e r79ae36dd  
    3939
    4040#include <clipboard.h>
    41 #include <ipc/ns.h>
     41#include <ns.h>
    4242#include <ipc/services.h>
    4343#include <ipc/clipboard.h>
     44#include <fibril_synch.h>
    4445#include <async.h>
    4546#include <str.h>
     
    4748#include <malloc.h>
    4849
    49 static int clip_phone = -1;
    50 
    51 /** Connect to clipboard server
    52  *
    53  */
    54 static void clip_connect(void)
    55 {
    56         while (clip_phone < 0)
    57                 clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0);
     50static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
     51static async_sess_t *clip_sess = NULL;
     52
     53/** Start an async exchange on the clipboard session.
     54 *
     55 * @return New exchange.
     56 *
     57 */
     58static async_exch_t *clip_exchange_begin(void)
     59{
     60        fibril_mutex_lock(&clip_mutex);
     61       
     62        while (clip_sess == NULL)
     63                clip_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     64                    SERVICE_CLIPBOARD, 0, 0);
     65       
     66        fibril_mutex_unlock(&clip_mutex);
     67       
     68        return async_exchange_begin(clip_sess);
     69}
     70
     71/** Finish an async exchange on the clipboard session.
     72 *
     73 * @param exch Exchange to be finished.
     74 *
     75 */
     76static void clip_exchange_end(async_exch_t *exch)
     77{
     78        async_exchange_end(exch);
    5879}
    5980
     
    7394       
    7495        if (size == 0) {
    75                 async_serialize_start();
    76                 clip_connect();
    77                
    78                 sysarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE);
    79                
    80                 async_serialize_end();
     96                async_exch_t *exch = clip_exchange_begin();
     97                sysarg_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA,
     98                    CLIPBOARD_TAG_NONE);
     99                clip_exchange_end(exch);
    81100               
    82101                return (int) rc;
    83102        } else {
    84                 async_serialize_start();
    85                 clip_connect();
    86                
    87                 aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
    88                 sysarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
     103                async_exch_t *exch = clip_exchange_begin();
     104                aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA,
     105                    NULL);
     106                sysarg_t rc = async_data_write_start(exch, (void *) str, size);
     107                clip_exchange_end(exch);
     108               
    89109                if (rc != EOK) {
    90110                        sysarg_t rc_orig;
    91111                        async_wait_for(req, &rc_orig);
    92                         async_serialize_end();
    93112                        if (rc_orig == EOK)
    94113                                return (int) rc;
     
    98117               
    99118                async_wait_for(req, &rc);
    100                 async_serialize_end();
    101119               
    102120                return (int) rc;
     
    117135        /* Loop until clipboard read succesful */
    118136        while (true) {
    119                 async_serialize_start();
    120                 clip_connect();
     137                async_exch_t *exch = clip_exchange_begin();
    121138               
    122139                sysarg_t size;
    123140                sysarg_t tag;
    124                 sysarg_t rc = async_req_0_2(clip_phone, CLIPBOARD_CONTENT, &size, &tag);
    125                
    126                 async_serialize_end();
     141                sysarg_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag);
     142               
     143                clip_exchange_end(exch);
    127144               
    128145                if (rc != EOK)
     
    145162                                return ENOMEM;
    146163                       
    147                         async_serialize_start();
    148                        
    149                         aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL);
    150                         rc = async_data_read_start(clip_phone, (void *) sbuf, size);
     164                        exch = clip_exchange_begin();
     165                        aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL);
     166                        rc = async_data_read_start(exch, (void *) sbuf, size);
     167                        clip_exchange_end(exch);
     168                       
    151169                        if ((int) rc == EOVERFLOW) {
    152170                                /*
     
    154172                                 * the last call of CLIPBOARD_CONTENT
    155173                                 */
    156                                 async_serialize_end();
    157174                                break;
    158175                        }
     
    161178                                sysarg_t rc_orig;
    162179                                async_wait_for(req, &rc_orig);
    163                                 async_serialize_end();
    164180                                if (rc_orig == EOK)
    165181                                        return (int) rc;
     
    169185                       
    170186                        async_wait_for(req, &rc);
    171                         async_serialize_end();
    172187                       
    173188                        if (rc == EOK) {
  • uspace/lib/c/generic/device/char_dev.c

    r764d71e r79ae36dd  
    4545 * using its character interface.
    4646 *
    47  * @param dev_phone     Phone to the device.
    48  * @param buf           Buffer for the data read from or written to the device.
    49  * @param size          Maximum size of data (in bytes) to be read or written.
    50  * @param read          Read from the device if true, write to it otherwise.
     47 * @param sess Session to the device.
     48 * @param buf  Buffer for the data read from or written to the device.
     49 * @param size Maximum size of data (in bytes) to be read or written.
     50 * @param read Read from the device if true, write to it otherwise.
    5151 *
    52  * @return              Non-negative number of bytes actually read from or
    53  *                      written to the device on success, negative error number
    54  *                      otherwise.
     52 * @return Non-negative number of bytes actually read from or
     53 *         written to the device on success, negative error number
     54 *         otherwise.
     55 *
    5556 */
    56 static ssize_t char_dev_rw(int dev_phone, void *buf, size_t size, bool read)
     57static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read)
    5758{
    58         async_serialize_start();
    59        
    6059        ipc_call_t answer;
    6160        aid_t req;
    6261        int ret;
    6362       
     63        async_exch_t *exch = async_exchange_begin(sess);
     64       
    6465        if (read) {
    65                 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
     66                req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
    6667                    CHAR_DEV_READ, &answer);
    67                 ret = async_data_read_start(dev_phone, buf, size);
     68                ret = async_data_read_start(exch, buf, size);
    6869        } else {
    69                 req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
     70                req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
    7071                    CHAR_DEV_WRITE, &answer);
    71                 ret = async_data_write_start(dev_phone, buf, size);
     72                ret = async_data_write_start(exch, buf, size);
    7273        }
     74       
     75        async_exchange_end(exch);
    7376       
    7477        sysarg_t rc;
    7578        if (ret != EOK) {
    7679                async_wait_for(req, &rc);
    77                 async_serialize_end();
    7880                if (rc == EOK)
    7981                        return (ssize_t) ret;
     
    8385       
    8486        async_wait_for(req, &rc);
    85         async_serialize_end();
    8687       
    8788        ret = (int) rc;
     
    9495/** Read from character device.
    9596 *
    96  * @param dev_phone     Phone to the device.
    97  * @param buf           Output buffer for the data read from the device.
    98  * @param size          Maximum size (in bytes) of the data to be read.
     97 * @param sess Session to the device.
     98 * @param buf  Output buffer for the data read from the device.
     99 * @param size Maximum size (in bytes) of the data to be read.
    99100 *
    100  * @return              Non-negative number of bytes actually read from the
    101  *                      device on success, negative error number otherwise.
     101 * @return Non-negative number of bytes actually read from the
     102 *         device on success, negative error number otherwise.
     103 *
    102104 */
    103 ssize_t char_dev_read(int dev_phone, void *buf, size_t size)
     105ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size)
    104106{
    105         return char_dev_rw(dev_phone, buf, size, true);
     107        return char_dev_rw(sess, buf, size, true);
    106108}
    107109
    108110/** Write to character device.
    109111 *
    110  * @param dev_phone     Phone to the device.
    111  * @param buf           Input buffer containg the data to be written to the
    112  *                      device.
    113  * @param size          Maximum size (in bytes) of the data to be written.
     112 * @param sess Session to the device.
     113 * @param buf  Input buffer containg the data to be written to the
     114 *             device.
     115 * @param size Maximum size (in bytes) of the data to be written.
    114116 *
    115  * @return              Non-negative number of bytes actually written to the
    116  *                      device on success, negative error number otherwise.
     117 * @return Non-negative number of bytes actually written to the
     118 *         device on success, negative error number otherwise.
     119 *
    117120 */
    118 ssize_t char_dev_write(int dev_phone, void *buf, size_t size)
     121ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size)
    119122{
    120         return char_dev_rw(dev_phone, buf, size, false);
     123        return char_dev_rw(sess, buf, size, false);
    121124}
    122125
  • uspace/lib/c/generic/device/hw_res.c

    r764d71e r79ae36dd  
    3838#include <malloc.h>
    3939
    40 int hw_res_get_resource_list(int dev_phone, hw_resource_list_t *hw_resources)
     40int hw_res_get_resource_list(async_sess_t *sess,
     41    hw_resource_list_t *hw_resources)
    4142{
    4243        sysarg_t count = 0;
    43 
    44         int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
     44       
     45        async_exch_t *exch = async_exchange_begin(sess);
     46        int rc = async_req_1_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
    4547            HW_RES_GET_RESOURCE_LIST, &count);
    46 
    47         hw_resources->count = count;
    48         if (rc != EOK)
     48       
     49        if (rc != EOK) {
     50                async_exchange_end(exch);
    4951                return rc;
     52        }
    5053       
    5154        size_t size = count * sizeof(hw_resource_t);
    52         hw_resources->resources = (hw_resource_t *)malloc(size);
    53         if (!hw_resources->resources)
     55        hw_resource_t *resources = (hw_resource_t *) malloc(size);
     56        if (resources == NULL) {
     57                // FIXME: This is protocol violation
     58                async_exchange_end(exch);
    5459                return ENOMEM;
     60        }
    5561       
    56         rc = async_data_read_start(dev_phone, hw_resources->resources, size);
     62        rc = async_data_read_start(exch, resources, size);
     63        async_exchange_end(exch);
     64       
    5765        if (rc != EOK) {
    58                 free(hw_resources->resources);
    59                 hw_resources->resources = NULL;
     66                free(resources);
    6067                return rc;
    6168        }
     69       
     70        hw_resources->resources = resources;
     71        hw_resources->count = count;
    6272       
    6373        return EOK;
    6474}
    6575
    66 bool hw_res_enable_interrupt(int dev_phone)
     76bool hw_res_enable_interrupt(async_sess_t *sess)
    6777{
    68         int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
     78        async_exch_t *exch = async_exchange_begin(sess);
     79        int rc = async_req_1_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
    6980            HW_RES_ENABLE_INTERRUPT);
    70 
    71         return rc == EOK;
     81        async_exchange_end(exch);
     82       
     83        return (rc == EOK);
    7284}
    7385
  • uspace/lib/c/generic/devman.c

    r764d71e r79ae36dd  
    3636
    3737#include <str.h>
    38 #include <stdio.h>
    3938#include <ipc/services.h>
     39#include <ns.h>
    4040#include <ipc/devman.h>
    4141#include <devman.h>
     42#include <fibril_synch.h>
    4243#include <async.h>
    43 #include <fibril_synch.h>
    4444#include <errno.h>
    4545#include <malloc.h>
    4646#include <bool.h>
    47 #include <adt/list.h>
    48 
    49 static int devman_phone_driver = -1;
    50 static int devman_phone_client = -1;
    51 
    52 static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
    53 
    54 int devman_get_phone(devman_interface_t iface, unsigned int flags)
     47
     48static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex);
     49static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex);
     50
     51static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex);
     52static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex);
     53
     54static async_sess_t *devman_driver_block_sess = NULL;
     55static async_sess_t *devman_client_block_sess = NULL;
     56
     57static async_sess_t *devman_driver_sess = NULL;
     58static async_sess_t *devman_client_sess = NULL;
     59
     60static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
     61    async_sess_t **dst)
     62{
     63        fibril_mutex_lock(mtx);
     64       
     65        if ((*dst == NULL) && (src != NULL))
     66                *dst = src;
     67       
     68        fibril_mutex_unlock(mtx);
     69}
     70
     71/** Start an async exchange on the devman session (blocking).
     72 *
     73 * @param iface Device manager interface to choose
     74 *
     75 * @return New exchange.
     76 *
     77 */
     78async_exch_t *devman_exchange_begin_blocking(devman_interface_t iface)
    5579{
    5680        switch (iface) {
    5781        case DEVMAN_DRIVER:
    58                 fibril_mutex_lock(&devman_phone_mutex);
    59                 if (devman_phone_driver >= 0) {
    60                         fibril_mutex_unlock(&devman_phone_mutex);
    61                         return devman_phone_driver;
     82                fibril_mutex_lock(&devman_driver_block_mutex);
     83               
     84                while (devman_driver_block_sess == NULL) {
     85                        clone_session(&devman_driver_mutex, devman_driver_sess,
     86                            &devman_driver_block_sess);
     87                       
     88                        if (devman_driver_block_sess == NULL)
     89                                devman_driver_block_sess =
     90                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     91                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    6292                }
    6393               
    64                 if (flags & IPC_FLAG_BLOCKING)
    65                         devman_phone_driver = async_connect_me_to_blocking(
    66                             PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    67                 else
    68                         devman_phone_driver = async_connect_me_to(PHONE_NS,
    69                             SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    70                
    71                 fibril_mutex_unlock(&devman_phone_mutex);
    72                 return devman_phone_driver;
     94                fibril_mutex_unlock(&devman_driver_block_mutex);
     95               
     96                clone_session(&devman_driver_mutex, devman_driver_block_sess,
     97                    &devman_driver_sess);
     98               
     99                return async_exchange_begin(devman_driver_block_sess);
    73100        case DEVMAN_CLIENT:
    74                 fibril_mutex_lock(&devman_phone_mutex);
    75                 if (devman_phone_client >= 0) {
    76                         fibril_mutex_unlock(&devman_phone_mutex);
    77                         return devman_phone_client;
     101                fibril_mutex_lock(&devman_client_block_mutex);
     102               
     103                while (devman_client_block_sess == NULL) {
     104                        clone_session(&devman_client_mutex, devman_client_sess,
     105                            &devman_client_block_sess);
     106                       
     107                        if (devman_client_block_sess == NULL)
     108                                devman_client_block_sess =
     109                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     110                                    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    78111                }
    79112               
    80                 if (flags & IPC_FLAG_BLOCKING) {
    81                         devman_phone_client = async_connect_me_to_blocking(
    82                             PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    83                 } else {
    84                         devman_phone_client = async_connect_me_to(PHONE_NS,
    85                             SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    86                 }
    87                
    88                 fibril_mutex_unlock(&devman_phone_mutex);
    89                 return devman_phone_client;
     113                fibril_mutex_unlock(&devman_client_block_mutex);
     114               
     115                clone_session(&devman_client_mutex, devman_client_block_sess,
     116                    &devman_client_sess);
     117               
     118                return async_exchange_begin(devman_client_block_sess);
    90119        default:
    91                 return -1;
    92         }
     120                return NULL;
     121        }
     122}
     123
     124/** Start an async exchange on the devman session.
     125 *
     126 * @param iface Device manager interface to choose
     127 *
     128 * @return New exchange.
     129 *
     130 */
     131async_exch_t *devman_exchange_begin(devman_interface_t iface)
     132{
     133        switch (iface) {
     134        case DEVMAN_DRIVER:
     135                fibril_mutex_lock(&devman_driver_mutex);
     136               
     137                if (devman_driver_sess == NULL)
     138                        devman_driver_sess =
     139                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     140                            DEVMAN_DRIVER, 0);
     141               
     142                fibril_mutex_unlock(&devman_driver_mutex);
     143               
     144                if (devman_driver_sess == NULL)
     145                        return NULL;
     146               
     147                return async_exchange_begin(devman_driver_sess);
     148        case DEVMAN_CLIENT:
     149                fibril_mutex_lock(&devman_client_mutex);
     150               
     151                if (devman_client_sess == NULL)
     152                        devman_client_sess =
     153                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     154                            DEVMAN_CLIENT, 0);
     155               
     156                fibril_mutex_unlock(&devman_client_mutex);
     157               
     158                if (devman_client_sess == NULL)
     159                        return NULL;
     160               
     161                return async_exchange_begin(devman_client_sess);
     162        default:
     163                return NULL;
     164        }
     165}
     166
     167/** Finish an async exchange on the devman session.
     168 *
     169 * @param exch Exchange to be finished.
     170 *
     171 */
     172void devman_exchange_end(async_exch_t *exch)
     173{
     174        async_exchange_end(exch);
    93175}
    94176
     
    96178int devman_driver_register(const char *name, async_client_conn_t conn)
    97179{
    98         int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    99        
    100         if (phone < 0)
    101                 return phone;
    102        
    103         async_serialize_start();
    104        
    105         ipc_call_t answer;
    106         aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
    107        
    108         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
    109         if (retval != EOK) {
    110                 async_wait_for(req, NULL);
    111                 async_serialize_end();
    112                 return -1;
     180        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     181       
     182        ipc_call_t answer;
     183        aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
     184        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     185       
     186        devman_exchange_end(exch);
     187       
     188        if (retval != EOK) {
     189                async_wait_for(req, NULL);
     190                return retval;
    113191        }
    114192       
    115193        async_set_client_connection(conn);
    116194       
    117         async_connect_to_me(phone, 0, 0, 0, NULL);
     195        exch = devman_exchange_begin(DEVMAN_DRIVER);
     196        async_connect_to_me(exch, 0, 0, 0, NULL);
     197        devman_exchange_end(exch);
     198       
    118199        async_wait_for(req, &retval);
    119        
    120         async_serialize_end();
    121        
    122200        return retval;
    123201}
    124202
    125 static int devman_send_match_id(int phone, match_id_t *match_id)
    126 {
    127         ipc_call_t answer;
    128 
    129         aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
    130             &answer);
    131         int retval = async_data_write_start(phone, match_id->id,
    132             str_size(match_id->id));
    133 
    134         async_wait_for(req, NULL);
    135         return retval;
    136 }
    137 
    138 
    139 static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
    140 {
     203/** Add function to a device.
     204 *
     205 * Request devman to add a new function to the specified device owned by
     206 * this driver task.
     207 *
     208 * @param name      Name of the new function
     209 * @param ftype     Function type, fun_inner or fun_exposed
     210 * @param match_ids Match IDs (should be empty for fun_exposed)
     211 * @param devh      Devman handle of the device
     212 * @param funh      Place to store handle of the new function
     213 *
     214 * @return EOK on success or negative error code.
     215 *
     216 */
     217int devman_add_function(const char *name, fun_type_t ftype,
     218    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
     219{
     220        int match_count = list_count(&match_ids->ids);
     221        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     222       
     223        ipc_call_t answer;
     224        aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
     225            devh, match_count, &answer);
     226        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     227        if (retval != EOK) {
     228                devman_exchange_end(exch);
     229                async_wait_for(req, NULL);
     230                return retval;
     231        }
     232       
     233        async_wait_for(req, &retval);
     234        if (retval != EOK) {
     235                devman_exchange_end(exch);
     236               
     237                if (funh != NULL)
     238                        *funh = -1;
     239               
     240                return retval;
     241        }
     242       
     243        if (funh != NULL)
     244                *funh = (int) IPC_GET_ARG1(answer);
     245       
    141246        link_t *link = match_ids->ids.next;
    142247        match_id_t *match_id = NULL;
    143         int ret = EOK;
    144 
     248       
    145249        while (link != &match_ids->ids) {
    146                 match_id = list_get_instance(link, match_id_t, link);
    147                 ret = devman_send_match_id(phone, match_id);
    148                 if (ret != EOK) {
    149                         return ret;
     250                match_id = list_get_instance(link, match_id_t, link);
     251               
     252                ipc_call_t answer;
     253                aid_t req = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
     254                    match_id->score, &answer);
     255                retval = async_data_write_start(exch, match_id->id,
     256                    str_size(match_id->id));
     257                if (retval != EOK) {
     258                        devman_exchange_end(exch);
     259                        async_wait_for(req, NULL);
     260                        return retval;
    150261                }
    151 
     262               
     263                async_wait_for(req, &retval);
     264                if (retval != EOK) {
     265                        devman_exchange_end(exch);
     266                        return retval;
     267                }
     268               
    152269                link = link->next;
    153270        }
    154 
    155         return ret;
    156 }
    157 
    158 /** Add function to a device.
    159  *
    160  * Request devman to add a new function to the specified device owned by
    161  * this driver task.
    162  *
    163  * @param name          Name of the new function
    164  * @param ftype         Function type, fun_inner or fun_exposed
    165  * @param match_ids     Match IDs (should be empty for fun_exposed)
    166  * @param devh          Devman handle of the device
    167  * @param funh          Place to store handle of the new function
    168  *
    169  * @return              EOK on success or negative error code.
    170  */
    171 int devman_add_function(const char *name, fun_type_t ftype,
    172     match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
    173 {
    174         int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    175         int fun_handle;
    176        
    177         if (phone < 0)
    178                 return phone;
    179        
    180         async_serialize_start();
    181        
    182         int match_count = list_count(&match_ids->ids);
    183         ipc_call_t answer;
    184 
    185         aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
    186             devh, match_count, &answer);
    187 
    188         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
    189         if (retval != EOK) {
    190                 async_wait_for(req, NULL);
    191                 async_serialize_end();
    192                 return retval;
    193         }
    194        
    195         int match_ids_rc = devman_send_match_ids(phone, match_ids);
    196        
    197         async_wait_for(req, &retval);
    198        
    199         async_serialize_end();
    200        
    201         /* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */
    202         if ((match_ids_rc != EOK) && (retval == EOK)) {
    203                 retval = match_ids_rc;
    204         }
    205 
    206         if (retval == EOK)
    207                 fun_handle = (int) IPC_GET_ARG1(answer);
    208         else
    209                 fun_handle = -1;
    210        
    211         *funh = fun_handle;
    212 
    213         return retval;
     271       
     272        devman_exchange_end(exch);
     273        return EOK;
    214274}
    215275
     
    217277    const char *class_name)
    218278{
    219         int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
    220        
    221         if (phone < 0)
    222                 return phone;
    223        
    224         async_serialize_start();
    225         ipc_call_t answer;
    226         aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
     279        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
     280       
     281        ipc_call_t answer;
     282        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
    227283            devman_handle, &answer);
    228        
    229         sysarg_t retval = async_data_write_start(phone, class_name,
     284        sysarg_t retval = async_data_write_start(exch, class_name,
    230285            str_size(class_name));
    231         if (retval != EOK) {
    232                 async_wait_for(req, NULL);
    233                 async_serialize_end();
     286       
     287        devman_exchange_end(exch);
     288       
     289        if (retval != EOK) {
     290                async_wait_for(req, NULL);
    234291                return retval;
    235292        }
    236293       
    237294        async_wait_for(req, &retval);
    238         async_serialize_end();
    239        
    240295        return retval;
    241296}
    242297
    243 void devman_hangup_phone(devman_interface_t iface)
    244 {
    245         switch (iface) {
    246         case DEVMAN_DRIVER:
    247                 if (devman_phone_driver >= 0) {
    248                         async_hangup(devman_phone_driver);
    249                         devman_phone_driver = -1;
    250                 }
    251                 break;
    252         case DEVMAN_CLIENT:
    253                 if (devman_phone_client >= 0) {
    254                         async_hangup(devman_phone_client);
    255                         devman_phone_client = -1;
    256                 }
    257                 break;
    258         default:
    259                 break;
    260         }
    261 }
    262 
    263 int devman_device_connect(devman_handle_t handle, unsigned int flags)
    264 {
    265         int phone;
    266        
    267         if (flags & IPC_FLAG_BLOCKING) {
    268                 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
    269                     DEVMAN_CONNECT_TO_DEVICE, handle);
    270         } else {
    271                 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
    272                     DEVMAN_CONNECT_TO_DEVICE, handle);
    273         }
    274        
    275         return phone;
    276 }
    277 
    278 int devman_parent_device_connect(devman_handle_t handle, unsigned int flags)
    279 {
    280         int phone;
    281        
    282         if (flags & IPC_FLAG_BLOCKING) {
    283                 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
    284                     DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    285         } else {
    286                 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
    287                     DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    288         }
    289        
    290         return phone;
     298async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle,
     299    unsigned int flags)
     300{
     301        async_sess_t *sess;
     302       
     303        if (flags & IPC_FLAG_BLOCKING)
     304                sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
     305                            DEVMAN_CONNECT_TO_DEVICE, handle);
     306        else
     307                sess = service_connect(mgmt, SERVICE_DEVMAN,
     308                            DEVMAN_CONNECT_TO_DEVICE, handle);
     309       
     310        return sess;
     311}
     312
     313async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
     314    devman_handle_t handle, unsigned int flags)
     315{
     316        async_sess_t *sess;
     317       
     318        if (flags & IPC_FLAG_BLOCKING)
     319                sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
     320                            DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
     321        else
     322                sess = service_connect(mgmt, SERVICE_DEVMAN,
     323                            DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
     324       
     325        return sess;
    291326}
    292327
     
    294329    unsigned int flags)
    295330{
    296         int phone = devman_get_phone(DEVMAN_CLIENT, flags);
    297        
    298         if (phone < 0)
    299                 return phone;
    300        
    301         async_serialize_start();
    302        
    303         ipc_call_t answer;
    304         aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
     331        async_exch_t *exch;
     332       
     333        if (flags & IPC_FLAG_BLOCKING)
     334                exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     335        else {
     336                exch = devman_exchange_begin(DEVMAN_CLIENT);
     337                if (exch == NULL)
     338                        return errno;
     339        }
     340       
     341        ipc_call_t answer;
     342        aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
    305343            &answer);
    306        
    307         sysarg_t retval = async_data_write_start(phone, pathname,
     344        sysarg_t retval = async_data_write_start(exch, pathname,
    308345            str_size(pathname));
    309         if (retval != EOK) {
    310                 async_wait_for(req, NULL);
    311                 async_serialize_end();
     346       
     347        devman_exchange_end(exch);
     348       
     349        if (retval != EOK) {
     350                async_wait_for(req, NULL);
    312351                return retval;
    313352        }
    314353       
    315354        async_wait_for(req, &retval);
    316        
    317         async_serialize_end();
    318355       
    319356        if (retval != EOK) {
    320357                if (handle != NULL)
    321358                        *handle = (devman_handle_t) -1;
     359               
    322360                return retval;
    323361        }
     
    332370    const char *devname, devman_handle_t *handle, unsigned int flags)
    333371{
    334         int phone = devman_get_phone(DEVMAN_CLIENT, flags);
    335 
    336         if (phone < 0)
    337                 return phone;
    338 
    339         async_serialize_start();
    340 
    341         ipc_call_t answer;
    342         aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     372        async_exch_t *exch;
     373       
     374        if (flags & IPC_FLAG_BLOCKING)
     375                exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     376        else {
     377                exch = devman_exchange_begin(DEVMAN_CLIENT);
     378                if (exch == NULL)
     379                        return errno;
     380        }
     381       
     382        ipc_call_t answer;
     383        aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
    343384            flags, &answer);
    344 
    345         sysarg_t retval = async_data_write_start(phone, classname,
     385        sysarg_t retval = async_data_write_start(exch, classname,
    346386            str_size(classname));
    347         if (retval != EOK) {
    348                 async_wait_for(req, NULL);
    349                 async_serialize_end();
    350                 return retval;
    351         }
    352         retval = async_data_write_start(phone, devname,
     387       
     388        if (retval != EOK) {
     389                devman_exchange_end(exch);
     390                async_wait_for(req, NULL);
     391                return retval;
     392        }
     393       
     394        retval = async_data_write_start(exch, devname,
    353395            str_size(devname));
    354         if (retval != EOK) {
    355                 async_wait_for(req, NULL);
    356                 async_serialize_end();
    357                 return retval;
    358         }
    359 
     396       
     397        devman_exchange_end(exch);
     398       
     399        if (retval != EOK) {
     400                async_wait_for(req, NULL);
     401                return retval;
     402        }
     403       
    360404        async_wait_for(req, &retval);
    361 
    362         async_serialize_end();
    363 
     405       
    364406        if (retval != EOK) {
    365407                if (handle != NULL)
    366408                        *handle = (devman_handle_t) -1;
    367                 return retval;
    368         }
    369 
     409               
     410                return retval;
     411        }
     412       
    370413        if (handle != NULL)
    371414                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
    372 
     415       
    373416        return retval;
    374417}
     
    376419int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    377420{
    378         int phone = devman_get_phone(DEVMAN_CLIENT, 0);
    379 
    380         if (phone < 0)
    381                 return phone;
    382 
    383         async_serialize_start();
    384 
    385         ipc_call_t answer;
    386         aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH,
     421        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     422        if (exch == NULL)
     423                return errno;
     424       
     425        ipc_call_t answer;
     426        aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
    387427            handle, &answer);
    388 
     428       
    389429        ipc_call_t data_request_call;
    390         aid_t data_request = async_data_read(phone, path, path_size,
     430        aid_t data_request = async_data_read(exch, path, path_size,
    391431            &data_request_call);
     432       
     433        devman_exchange_end(exch);
     434       
    392435        if (data_request == 0) {
    393436                async_wait_for(req, NULL);
    394                 async_serialize_end();
    395437                return ENOMEM;
    396438        }
    397 
     439       
    398440        sysarg_t data_request_rc;
     441        async_wait_for(data_request, &data_request_rc);
     442       
    399443        sysarg_t opening_request_rc;
    400         async_wait_for(data_request, &data_request_rc);
    401444        async_wait_for(req, &opening_request_rc);
    402 
    403         async_serialize_end();
    404 
     445       
    405446        if (data_request_rc != EOK) {
    406447                /* Prefer the return code of the opening request. */
    407                 if (opening_request_rc != EOK) {
     448                if (opening_request_rc != EOK)
    408449                        return (int) opening_request_rc;
    409                 } else {
     450                else
    410451                        return (int) data_request_rc;
    411                 }
    412         }
    413         if (opening_request_rc != EOK) {
     452        }
     453       
     454        if (opening_request_rc != EOK)
    414455                return (int) opening_request_rc;
    415         }
    416 
     456       
    417457        /* To be on the safe-side. */
    418458        path[path_size - 1] = 0;
    419 
    420459        size_t transferred_size = IPC_GET_ARG2(data_request_call);
    421 
    422         if (transferred_size >= path_size) {
     460        if (transferred_size >= path_size)
    423461                return ELIMIT;
    424         }
    425 
     462       
    426463        /* Terminate the string (trailing 0 not send over IPC). */
    427464        path[transferred_size] = 0;
    428 
    429465        return EOK;
    430466}
    431467
    432 
    433468/** @}
    434469 */
  • uspace/lib/c/generic/devmap.c

    r764d71e r79ae36dd  
    3030#include <str.h>
    3131#include <ipc/services.h>
    32 #include <ipc/ns.h>
     32#include <ns.h>
    3333#include <ipc/devmap.h>
    3434#include <devmap.h>
     35#include <fibril_synch.h>
    3536#include <async.h>
    3637#include <errno.h>
     
    3839#include <bool.h>
    3940
    40 static int devmap_phone_driver = -1;
    41 static int devmap_phone_client = -1;
    42 
    43 /** Get phone to device mapper task. */
    44 int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
     41static FIBRIL_MUTEX_INITIALIZE(devmap_driver_block_mutex);
     42static FIBRIL_MUTEX_INITIALIZE(devmap_client_block_mutex);
     43
     44static FIBRIL_MUTEX_INITIALIZE(devmap_driver_mutex);
     45static FIBRIL_MUTEX_INITIALIZE(devmap_client_mutex);
     46
     47static async_sess_t *devmap_driver_block_sess = NULL;
     48static async_sess_t *devmap_client_block_sess = NULL;
     49
     50static async_sess_t *devmap_driver_sess = NULL;
     51static async_sess_t *devmap_client_sess = NULL;
     52
     53static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
     54    async_sess_t **dst)
     55{
     56        fibril_mutex_lock(mtx);
     57       
     58        if ((*dst == NULL) && (src != NULL))
     59                *dst = src;
     60       
     61        fibril_mutex_unlock(mtx);
     62}
     63
     64/** Start an async exchange on the devmap session (blocking).
     65 *
     66 * @param iface Device mapper interface to choose
     67 *
     68 * @return New exchange.
     69 *
     70 */
     71async_exch_t *devmap_exchange_begin_blocking(devmap_interface_t iface)
    4572{
    4673        switch (iface) {
    4774        case DEVMAP_DRIVER:
    48                 if (devmap_phone_driver >= 0)
    49                         return devmap_phone_driver;
    50                
    51                 if (flags & IPC_FLAG_BLOCKING)
    52                         devmap_phone_driver = service_connect_blocking(SERVICE_DEVMAP,
    53                             DEVMAP_DRIVER, 0);
    54                 else
    55                         devmap_phone_driver = service_connect(SERVICE_DEVMAP,
    56                             DEVMAP_DRIVER, 0);
    57                
    58                 return devmap_phone_driver;
     75                fibril_mutex_lock(&devmap_driver_block_mutex);
     76               
     77                while (devmap_driver_block_sess == NULL) {
     78                        clone_session(&devmap_driver_mutex, devmap_driver_sess,
     79                            &devmap_driver_block_sess);
     80                       
     81                        if (devmap_driver_block_sess == NULL)
     82                                devmap_driver_block_sess =
     83                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     84                                    SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
     85                }
     86               
     87                fibril_mutex_unlock(&devmap_driver_block_mutex);
     88               
     89                clone_session(&devmap_driver_mutex, devmap_driver_block_sess,
     90                    &devmap_driver_sess);
     91               
     92                return async_exchange_begin(devmap_driver_block_sess);
    5993        case DEVMAP_CLIENT:
    60                 if (devmap_phone_client >= 0)
    61                         return devmap_phone_client;
    62                
    63                 if (flags & IPC_FLAG_BLOCKING)
    64                         devmap_phone_client = service_connect_blocking(SERVICE_DEVMAP,
    65                             DEVMAP_CLIENT, 0);
    66                 else
    67                         devmap_phone_client = service_connect(SERVICE_DEVMAP,
    68                             DEVMAP_CLIENT, 0);
    69                
    70                 return devmap_phone_client;
     94                fibril_mutex_lock(&devmap_client_block_mutex);
     95               
     96                while (devmap_client_block_sess == NULL) {
     97                        clone_session(&devmap_client_mutex, devmap_client_sess,
     98                            &devmap_client_block_sess);
     99                       
     100                        if (devmap_client_block_sess == NULL)
     101                                devmap_client_block_sess =
     102                                    service_connect_blocking(EXCHANGE_SERIALIZE,
     103                                    SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
     104                }
     105               
     106                fibril_mutex_unlock(&devmap_client_block_mutex);
     107               
     108                clone_session(&devmap_client_mutex, devmap_client_block_sess,
     109                    &devmap_client_sess);
     110               
     111                return async_exchange_begin(devmap_client_block_sess);
    71112        default:
    72                 return -1;
    73         }
    74 }
    75 
    76 void devmap_hangup_phone(devmap_interface_t iface)
     113                return NULL;
     114        }
     115}
     116
     117/** Start an async exchange on the devmap session.
     118 *
     119 * @param iface Device mapper interface to choose
     120 *
     121 * @return New exchange.
     122 *
     123 */
     124async_exch_t *devmap_exchange_begin(devmap_interface_t iface)
    77125{
    78126        switch (iface) {
    79127        case DEVMAP_DRIVER:
    80                 if (devmap_phone_driver >= 0) {
    81                         async_hangup(devmap_phone_driver);
    82                         devmap_phone_driver = -1;
    83                 }
    84                 break;
     128                fibril_mutex_lock(&devmap_driver_mutex);
     129               
     130                if (devmap_driver_sess == NULL)
     131                        devmap_driver_sess =
     132                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP,
     133                            DEVMAP_DRIVER, 0);
     134               
     135                fibril_mutex_unlock(&devmap_driver_mutex);
     136               
     137                if (devmap_driver_sess == NULL)
     138                        return NULL;
     139               
     140                return async_exchange_begin(devmap_driver_sess);
    85141        case DEVMAP_CLIENT:
    86                 if (devmap_phone_client >= 0) {
    87                         async_hangup(devmap_phone_client);
    88                         devmap_phone_client = -1;
    89                 }
    90                 break;
     142                fibril_mutex_lock(&devmap_client_mutex);
     143               
     144                if (devmap_client_sess == NULL)
     145                        devmap_client_sess =
     146                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP,
     147                            DEVMAP_CLIENT, 0);
     148               
     149                fibril_mutex_unlock(&devmap_client_mutex);
     150               
     151                if (devmap_client_sess == NULL)
     152                        return NULL;
     153               
     154                return async_exchange_begin(devmap_client_sess);
    91155        default:
    92                 break;
    93         }
     156                return NULL;
     157        }
     158}
     159
     160/** Finish an async exchange on the devmap session.
     161 *
     162 * @param exch Exchange to be finished.
     163 *
     164 */
     165void devmap_exchange_end(async_exch_t *exch)
     166{
     167        async_exchange_end(exch);
    94168}
    95169
     
    97171int devmap_driver_register(const char *name, async_client_conn_t conn)
    98172{
    99         int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
    100        
    101         if (phone < 0)
    102                 return phone;
    103        
    104         async_serialize_start();
     173        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER);
    105174       
    106175        ipc_call_t answer;
    107         aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
    108        
    109         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     176        aid_t req = async_send_2(exch, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
     177        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     178       
     179        devmap_exchange_end(exch);
     180       
    110181        if (retval != EOK) {
    111182                async_wait_for(req, NULL);
    112                 async_serialize_end();
    113                 return -1;
     183                return retval;
    114184        }
    115185       
    116186        async_set_client_connection(conn);
    117187       
    118         async_connect_to_me(phone, 0, 0, 0, NULL);
     188        exch = devmap_exchange_begin(DEVMAP_DRIVER);
     189        async_connect_to_me(exch, 0, 0, 0, NULL);
     190        devmap_exchange_end(exch);
     191       
    119192        async_wait_for(req, &retval);
    120        
    121         async_serialize_end();
    122        
    123193        return retval;
    124194}
     
    129199 * If not 0, the first argument is the interface and the second argument
    130200 * is the devmap handle of the device.
     201 *
    131202 * When the interface is zero (default), the first argument is directly
    132203 * the handle (to ensure backward compatibility).
    133204 *
    134  * @param fqdn Fully qualified device name.
    135  * @param[out] handle Handle to the created instance of device.
    136  * @param interface Interface when forwarding.
     205 * @param      fqdn      Fully qualified device name.
     206 * @param[out] handle    Handle to the created instance of device.
     207 * @param      interface Interface when forwarding.
    137208 *
    138209 */
     
    140211    devmap_handle_t *handle, sysarg_t interface)
    141212{
    142         int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
    143        
    144         if (phone < 0)
    145                 return phone;
    146        
    147         async_serialize_start();
     213        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER);
    148214       
    149215        ipc_call_t answer;
    150         aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, interface, 0,
     216        aid_t req = async_send_2(exch, DEVMAP_DEVICE_REGISTER, interface, 0,
    151217            &answer);
    152        
    153         sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
     218        sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn));
     219       
     220        devmap_exchange_end(exch);
     221       
    154222        if (retval != EOK) {
    155223                async_wait_for(req, NULL);
    156                 async_serialize_end();
    157224                return retval;
    158225        }
    159226       
    160227        async_wait_for(req, &retval);
    161        
    162         async_serialize_end();
    163228       
    164229        if (retval != EOK) {
    165230                if (handle != NULL)
    166231                        *handle = -1;
     232               
    167233                return retval;
    168234        }
     
    176242/** Register new device.
    177243 *
    178  * @param fqdn      Fully qualified device name.
    179  * @param handle    Output: Handle to the created instance of device.
     244 * @param fqdn   Fully qualified device name.
     245 * @param handle Output: Handle to the created instance of device.
    180246 *
    181247 */
     
    185251}
    186252
    187 
    188 int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, unsigned int flags)
    189 {
    190         int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
    191        
    192         if (phone < 0)
    193                 return phone;
    194        
    195         async_serialize_start();
     253int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle,
     254    unsigned int flags)
     255{
     256        async_exch_t *exch;
     257       
     258        if (flags & IPC_FLAG_BLOCKING)
     259                exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     260        else {
     261                exch = devmap_exchange_begin(DEVMAP_CLIENT);
     262                if (exch == NULL)
     263                        return errno;
     264        }
    196265       
    197266        ipc_call_t answer;
    198         aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
     267        aid_t req = async_send_2(exch, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
    199268            &answer);
    200        
    201         sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
     269        sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn));
     270       
     271        devmap_exchange_end(exch);
     272       
    202273        if (retval != EOK) {
    203274                async_wait_for(req, NULL);
    204                 async_serialize_end();
    205275                return retval;
    206276        }
    207277       
    208278        async_wait_for(req, &retval);
    209        
    210         async_serialize_end();
    211279       
    212280        if (retval != EOK) {
    213281                if (handle != NULL)
    214282                        *handle = (devmap_handle_t) -1;
     283               
    215284                return retval;
    216285        }
     
    222291}
    223292
    224 int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, unsigned int flags)
    225 {
    226         int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
    227        
    228         if (phone < 0)
    229                 return phone;
    230        
    231         async_serialize_start();
     293int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle,
     294    unsigned int flags)
     295{
     296        async_exch_t *exch;
     297       
     298        if (flags & IPC_FLAG_BLOCKING)
     299                exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     300        else {
     301                exch = devmap_exchange_begin(DEVMAP_CLIENT);
     302                if (exch == NULL)
     303                        return errno;
     304        }
    232305       
    233306        ipc_call_t answer;
    234         aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
     307        aid_t req = async_send_2(exch, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
    235308            &answer);
    236        
    237         sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     309        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     310       
     311        devmap_exchange_end(exch);
     312       
    238313        if (retval != EOK) {
    239314                async_wait_for(req, NULL);
    240                 async_serialize_end();
    241315                return retval;
    242316        }
    243317       
    244318        async_wait_for(req, &retval);
    245        
    246         async_serialize_end();
    247319       
    248320        if (retval != EOK) {
    249321                if (handle != NULL)
    250322                        *handle = (devmap_handle_t) -1;
     323               
    251324                return retval;
    252325        }
     
    260333devmap_handle_type_t devmap_handle_probe(devmap_handle_t handle)
    261334{
    262         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    263        
    264         if (phone < 0)
    265                 return phone;
     335        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
    266336       
    267337        sysarg_t type;
    268         int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
     338        int retval = async_req_1_1(exch, DEVMAP_HANDLE_PROBE, handle, &type);
     339       
     340        devmap_exchange_end(exch);
     341       
    269342        if (retval != EOK)
    270343                return DEV_HANDLE_NONE;
     
    273346}
    274347
    275 int devmap_device_connect(devmap_handle_t handle, unsigned int flags)
    276 {
    277         int phone;
    278        
    279         if (flags & IPC_FLAG_BLOCKING) {
    280                 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
     348async_sess_t *devmap_device_connect(exch_mgmt_t mgmt, devmap_handle_t handle,
     349    unsigned int flags)
     350{
     351        async_sess_t *sess;
     352       
     353        if (flags & IPC_FLAG_BLOCKING)
     354                sess = service_connect_blocking(mgmt, SERVICE_DEVMAP,
    281355                    DEVMAP_CONNECT_TO_DEVICE, handle);
    282         } else {
    283                 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
     356        else
     357                sess = service_connect(mgmt, SERVICE_DEVMAP,
    284358                    DEVMAP_CONNECT_TO_DEVICE, handle);
    285         }
    286        
    287         return phone;
     359       
     360        return sess;
    288361}
    289362
    290363int devmap_null_create(void)
    291364{
    292         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    293        
    294         if (phone < 0)
    295                 return -1;
     365        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
    296366       
    297367        sysarg_t null_id;
    298         int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
     368        int retval = async_req_0_1(exch, DEVMAP_NULL_CREATE, &null_id);
     369       
     370        devmap_exchange_end(exch);
     371       
    299372        if (retval != EOK)
    300373                return -1;
     
    305378void devmap_null_destroy(int null_id)
    306379{
    307         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    308        
    309         if (phone < 0)
    310                 return;
    311        
    312         async_req_1_0(phone, DEVMAP_NULL_DESTROY, (sysarg_t) null_id);
    313 }
    314 
    315 static size_t devmap_count_namespaces_internal(int phone)
     380        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     381        async_req_1_0(exch, DEVMAP_NULL_DESTROY, (sysarg_t) null_id);
     382        devmap_exchange_end(exch);
     383}
     384
     385static size_t devmap_count_namespaces_internal(async_exch_t *exch)
    316386{
    317387        sysarg_t count;
    318         int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
     388        int retval = async_req_0_1(exch, DEVMAP_GET_NAMESPACE_COUNT, &count);
    319389        if (retval != EOK)
    320390                return 0;
     
    323393}
    324394
    325 static size_t devmap_count_devices_internal(int phone, devmap_handle_t ns_handle)
     395static size_t devmap_count_devices_internal(async_exch_t *exch,
     396    devmap_handle_t ns_handle)
    326397{
    327398        sysarg_t count;
    328         int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
     399        int retval = async_req_1_1(exch, DEVMAP_GET_DEVICE_COUNT, ns_handle,
     400            &count);
    329401        if (retval != EOK)
    330402                return 0;
     
    335407size_t devmap_count_namespaces(void)
    336408{
    337         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    338        
    339         if (phone < 0)
    340                 return 0;
    341        
    342         return devmap_count_namespaces_internal(phone);
     409        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     410        size_t size = devmap_count_namespaces_internal(exch);
     411        devmap_exchange_end(exch);
     412       
     413        return size;
    343414}
    344415
    345416size_t devmap_count_devices(devmap_handle_t ns_handle)
    346417{
    347         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    348        
    349         if (phone < 0)
    350                 return 0;
    351        
    352         return devmap_count_devices_internal(phone, ns_handle);
     418        async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     419        size_t size = devmap_count_devices_internal(exch, ns_handle);
     420        devmap_exchange_end(exch);
     421       
     422        return size;
    353423}
    354424
    355425size_t devmap_get_namespaces(dev_desc_t **data)
    356426{
    357         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    358        
    359         if (phone < 0)
    360                 return 0;
    361        
    362427        /* Loop until namespaces read succesful */
    363428        while (true) {
    364                 size_t count = devmap_count_namespaces_internal(phone);
     429                async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     430                size_t count = devmap_count_namespaces_internal(exch);
     431                devmap_exchange_end(exch);
     432               
    365433                if (count == 0)
    366434                        return 0;
     
    370438                        return 0;
    371439               
    372                 async_serialize_start();
     440                exch = devmap_exchange_begin(DEVMAP_CLIENT);
    373441               
    374442                ipc_call_t answer;
    375                 aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
    376                
    377                 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     443                aid_t req = async_send_0(exch, DEVMAP_GET_NAMESPACES, &answer);
     444                int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t));
     445               
     446                devmap_exchange_end(exch);
     447               
    378448                if (rc == EOVERFLOW) {
    379449                        /*
     
    381451                         * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT
    382452                         */
    383                         async_serialize_end();
    384453                        free(devs);
    385454                        continue;
     
    388457                if (rc != EOK) {
    389458                        async_wait_for(req, NULL);
    390                         async_serialize_end();
    391459                        free(devs);
    392460                        return 0;
     
    395463                sysarg_t retval;
    396464                async_wait_for(req, &retval);
    397                 async_serialize_end();
    398465               
    399466                if (retval != EOK)
     
    407474size_t devmap_get_devices(devmap_handle_t ns_handle, dev_desc_t **data)
    408475{
    409         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    410        
    411         if (phone < 0)
    412                 return 0;
    413        
    414         /* Loop until namespaces read succesful */
     476        /* Loop until devices read succesful */
    415477        while (true) {
    416                 size_t count = devmap_count_devices_internal(phone, ns_handle);
     478                async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
     479                size_t count = devmap_count_devices_internal(exch, ns_handle);
     480                devmap_exchange_end(exch);
     481               
    417482                if (count == 0)
    418483                        return 0;
     
    422487                        return 0;
    423488               
    424                 async_serialize_start();
     489                exch = devmap_exchange_begin(DEVMAP_CLIENT);
    425490               
    426491                ipc_call_t answer;
    427                 aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
    428                
    429                 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     492                aid_t req = async_send_1(exch, DEVMAP_GET_DEVICES, ns_handle, &answer);
     493                int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t));
     494               
     495                devmap_exchange_end(exch);
     496               
    430497                if (rc == EOVERFLOW) {
    431498                        /*
     
    433500                         * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT
    434501                         */
    435                         async_serialize_end();
    436502                        free(devs);
    437503                        continue;
     
    440506                if (rc != EOK) {
    441507                        async_wait_for(req, NULL);
    442                         async_serialize_end();
    443508                        free(devs);
    444509                        return 0;
     
    447512                sysarg_t retval;
    448513                async_wait_for(req, &retval);
    449                 async_serialize_end();
    450514               
    451515                if (retval != EOK)
  • uspace/lib/c/generic/io/console.c

    r764d71e r79ae36dd  
    3737#include <libc.h>
    3838#include <async.h>
     39#include <errno.h>
     40#include <stdio.h>
     41#include <malloc.h>
     42#include <vfs/vfs_sess.h>
    3943#include <io/console.h>
    4044#include <ipc/console.h>
    4145
    42 void console_clear(int phone)
    43 {
    44         async_msg_0(phone, CONSOLE_CLEAR);
    45 }
    46 
    47 int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows)
    48 {
    49         return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows);
    50 }
    51 
    52 void console_set_style(int phone, uint8_t style)
    53 {
    54         async_msg_1(phone, CONSOLE_SET_STYLE, style);
    55 }
    56 
    57 void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
     46console_ctrl_t *console_init(FILE *ifile, FILE *ofile)
     47{
     48        console_ctrl_t *ctrl = malloc(sizeof(console_ctrl_t));
     49        if (!ctrl)
     50                return NULL;
     51       
     52        ctrl->input_sess = fsession(EXCHANGE_SERIALIZE, ifile);
     53        if (!ctrl->input_sess) {
     54                free(ctrl);
     55                return NULL;
     56        }
     57       
     58        ctrl->output_sess = fsession(EXCHANGE_SERIALIZE, ofile);
     59        if (!ctrl->output_sess) {
     60                free(ctrl);
     61                return NULL;
     62        }
     63       
     64        ctrl->input = ifile;
     65        ctrl->output = ofile;
     66        ctrl->input_aid = 0;
     67       
     68        return ctrl;
     69}
     70
     71void console_done(console_ctrl_t *ctrl)
     72{
     73        free(ctrl);
     74}
     75
     76bool console_kcon(void)
     77{
     78#if 0
     79        return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
     80#endif
     81       
     82        return false;
     83}
     84
     85void console_flush(console_ctrl_t *ctrl)
     86{
     87        fflush(ctrl->output);
     88}
     89
     90void console_clear(console_ctrl_t *ctrl)
     91{
     92        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     93        async_msg_0(exch, CONSOLE_CLEAR);
     94        async_exchange_end(exch);
     95}
     96
     97int console_get_size(console_ctrl_t *ctrl, sysarg_t *cols, sysarg_t *rows)
     98{
     99        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     100        int rc = async_req_0_2(exch, CONSOLE_GET_SIZE, cols, rows);
     101        async_exchange_end(exch);
     102       
     103        return rc;
     104}
     105
     106void console_set_style(console_ctrl_t *ctrl, uint8_t style)
     107{
     108        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     109        async_msg_1(exch, CONSOLE_SET_STYLE, style);
     110        async_exchange_end(exch);
     111}
     112
     113void console_set_color(console_ctrl_t *ctrl, uint8_t fg_color, uint8_t bg_color,
    58114    uint8_t flags)
    59115{
    60         async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
    61 }
    62 
    63 void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color)
    64 {
    65         async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
    66 }
    67 
    68 void console_cursor_visibility(int phone, bool show)
    69 {
    70         async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false));
    71 }
    72 
    73 int console_get_color_cap(int phone, sysarg_t *ccap)
    74 {
    75         return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap);
    76 }
    77 
    78 void console_kcon_enable(int phone)
    79 {
    80         async_msg_0(phone, CONSOLE_KCON_ENABLE);
    81 }
    82 
    83 int console_get_pos(int phone, sysarg_t *col, sysarg_t *row)
    84 {
    85         return async_req_0_2(phone, CONSOLE_GET_POS, col, row);
    86 }
    87 
    88 void console_set_pos(int phone, sysarg_t col, sysarg_t row)
    89 {
    90         async_msg_2(phone, CONSOLE_GOTO, col, row);
    91 }
    92 
    93 bool console_get_event(int phone, console_event_t *event)
    94 {
    95         sysarg_t type;
    96         sysarg_t key;
    97         sysarg_t mods;
    98         sysarg_t c;
    99        
    100         int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
    101         if (rc < 0)
     116        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     117        async_msg_3(exch, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
     118        async_exchange_end(exch);
     119}
     120
     121void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t fg_color,
     122    uint32_t bg_color)
     123{
     124        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     125        async_msg_2(exch, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
     126        async_exchange_end(exch);
     127}
     128
     129void console_cursor_visibility(console_ctrl_t *ctrl, bool show)
     130{
     131        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     132        async_msg_1(exch, CONSOLE_CURSOR_VISIBILITY, (show != false));
     133        async_exchange_end(exch);
     134}
     135
     136int console_get_color_cap(console_ctrl_t *ctrl, sysarg_t *ccap)
     137{
     138        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     139        int rc = async_req_0_1(exch, CONSOLE_GET_COLOR_CAP, ccap);
     140        async_exchange_end(exch);
     141       
     142        return rc;
     143}
     144
     145int console_get_pos(console_ctrl_t *ctrl, sysarg_t *col, sysarg_t *row)
     146{
     147        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     148        int rc = async_req_0_2(exch, CONSOLE_GET_POS, col, row);
     149        async_exchange_end(exch);
     150       
     151        return rc;
     152}
     153
     154void console_set_pos(console_ctrl_t *ctrl, sysarg_t col, sysarg_t row)
     155{
     156        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
     157        async_msg_2(exch, CONSOLE_GOTO, col, row);
     158        async_exchange_end(exch);
     159}
     160
     161bool console_get_kbd_event(console_ctrl_t *ctrl, kbd_event_t *event)
     162{
     163        if (ctrl->input_aid == 0) {
     164                sysarg_t type;
     165                sysarg_t key;
     166                sysarg_t mods;
     167                sysarg_t c;
     168               
     169                async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
     170                int rc = async_req_0_4(exch, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
     171                async_exchange_end(exch);
     172               
     173                if (rc != EOK) {
     174                        errno = rc;
     175                        return false;
     176                }
     177               
     178                event->type = type;
     179                event->key = key;
     180                event->mods = mods;
     181                event->c = c;
     182        } else {
     183                sysarg_t retval;
     184                async_wait_for(ctrl->input_aid, &retval);
     185               
     186                ctrl->input_aid = 0;
     187               
     188                if (retval != EOK) {
     189                        errno = (int) retval;
     190                        return false;
     191                }
     192               
     193                event->type = IPC_GET_ARG1(ctrl->input_call);
     194                event->key = IPC_GET_ARG2(ctrl->input_call);
     195                event->mods = IPC_GET_ARG3(ctrl->input_call);
     196                event->c = IPC_GET_ARG4(ctrl->input_call);
     197        }
     198       
     199        return true;
     200}
     201
     202bool console_get_kbd_event_timeout(console_ctrl_t *ctrl, kbd_event_t *event,
     203    suseconds_t *timeout)
     204{
     205        struct timeval t0;
     206        gettimeofday(&t0, NULL);
     207       
     208        if (ctrl->input_aid == 0) {
     209                async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
     210                ctrl->input_aid = async_send_0(exch, CONSOLE_GET_EVENT,
     211                    &ctrl->input_call);
     212                async_exchange_end(exch);
     213        }
     214       
     215        sysarg_t retval;
     216        int rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout);
     217        if (rc != EOK) {
     218                *timeout = 0;
     219                errno = rc;
    102220                return false;
    103        
    104         event->type = type;
    105         event->key = key;
    106         event->mods = mods;
    107         event->c = c;
     221        }
     222       
     223        ctrl->input_aid = 0;
     224       
     225        if (retval != EOK) {
     226                errno = (int) retval;
     227                return false;
     228        }
     229       
     230        event->type = IPC_GET_ARG1(ctrl->input_call);
     231        event->key = IPC_GET_ARG2(ctrl->input_call);
     232        event->mods = IPC_GET_ARG3(ctrl->input_call);
     233        event->c = IPC_GET_ARG4(ctrl->input_call);
     234       
     235        /* Update timeout */
     236        struct timeval t1;
     237        gettimeofday(&t1, NULL);
     238        *timeout -= tv_sub(&t1, &t0);
    108239       
    109240        return true;
  • uspace/lib/c/generic/io/io.c

    r764d71e r79ae36dd  
    4444#include <io/klog.h>
    4545#include <vfs/vfs.h>
     46#include <vfs/vfs_sess.h>
    4647#include <ipc/devmap.h>
    4748#include <adt/list.h>
    4849#include "../private/io.h"
     50#include "../private/stdio.h"
    4951
    5052static void _ffillbuf(FILE *stream);
     
    5658        .eof = true,
    5759        .klog = false,
    58         .phone = -1,
     60        .sess = NULL,
    5961        .btype = _IONBF,
    6062        .buf = NULL,
     
    7072        .eof = false,
    7173        .klog = true,
    72         .phone = -1,
     74        .sess = NULL,
    7375        .btype = _IOLBF,
    7476        .buf = NULL,
     
    8486        .eof = false,
    8587        .klog = true,
    86         .phone = -1,
     88        .sess = NULL,
    8789        .btype = _IONBF,
    8890        .buf = NULL,
     
    255257        stream->eof = false;
    256258        stream->klog = false;
    257         stream->phone = -1;
     259        stream->sess = NULL;
    258260        stream->need_sync = false;
    259261        _setvbuf(stream);
     
    277279        stream->eof = false;
    278280        stream->klog = false;
    279         stream->phone = -1;
     281        stream->sess = NULL;
    280282        stream->need_sync = false;
    281283        _setvbuf(stream);
     
    309311        stream->eof = false;
    310312        stream->klog = false;
    311         stream->phone = -1;
     313        stream->sess = NULL;
    312314        stream->need_sync = false;
    313315        _setvbuf(stream);
     
    324326        fflush(stream);
    325327       
    326         if (stream->phone >= 0)
    327                 async_hangup(stream->phone);
     328        if (stream->sess != NULL)
     329                async_hangup(stream->sess);
    328330       
    329331        if (stream->fd >= 0)
     
    732734        }
    733735       
    734         if (stream->fd >= 0 && stream->need_sync) {
     736        if ((stream->fd >= 0) && (stream->need_sync)) {
    735737                /**
    736738                 * Better than syncing always, but probably still not the
     
    770772}
    771773
    772 int fphone(FILE *stream)
     774async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream)
    773775{
    774776        if (stream->fd >= 0) {
    775                 if (stream->phone < 0)
    776                         stream->phone = fd_phone(stream->fd);
    777                
    778                 return stream->phone;
    779         }
    780        
    781         return -1;
     777                if (stream->sess == NULL)
     778                        stream->sess = fd_session(mgmt, stream->fd);
     779               
     780                return stream->sess;
     781        }
     782       
     783        return NULL;
    782784}
    783785
  • uspace/lib/c/generic/ipc.c

    r764d71e r79ae36dd  
    632632}
    633633
     634/** Request cloned connection.
     635 *
     636 * @param phoneid Phone handle used for contacting the other side.
     637 *
     638 * @return Cloned phone handle on success or a negative error code.
     639 *
     640 */
     641int ipc_connect_me(int phoneid)
     642{
     643        sysarg_t newphid;
     644        int res = ipc_call_sync_0_5(phoneid, IPC_M_CONNECT_ME, NULL, NULL,
     645            NULL, NULL, &newphid);
     646        if (res)
     647                return res;
     648       
     649        return newphid;
     650}
     651
    634652/** Request new connection.
    635653 *
  • uspace/lib/c/generic/libc.c

    r764d71e r79ae36dd  
    4949#include "private/libc.h"
    5050#include "private/async.h"
    51 #include "private/async_sess.h"
    5251#include "private/malloc.h"
    5352#include "private/io.h"
     
    6463        __malloc_init();
    6564        __async_init();
    66         __async_sess_init();
    6765       
    6866        fibril_t *fibril = fibril_setup();
  • uspace/lib/c/generic/loader.c

    r764d71e r79ae36dd  
    3535#include <ipc/loader.h>
    3636#include <ipc/services.h>
    37 #include <ipc/ns.h>
     37#include <ns.h>
    3838#include <libc.h>
    3939#include <task.h>
     
    4444#include <vfs/vfs.h>
    4545#include <loader/loader.h>
     46#include "private/loader.h"
    4647
    4748/** Connect to a new program loader.
     
    6364loader_t *loader_connect(void)
    6465{
    65         int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0);
    66         if (phone_id < 0)
    67                 return NULL;
    68        
    6966        loader_t *ldr = malloc(sizeof(loader_t));
    7067        if (ldr == NULL)
    7168                return NULL;
    7269       
    73         ldr->phone_id = phone_id;
     70        async_sess_t *sess =
     71            service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOAD, 0, 0);
     72        if (sess == NULL) {
     73                free(ldr);
     74                return NULL;
     75        }
     76       
     77        ldr->sess = sess;
    7478        return ldr;
    7579}
     
    8892{
    8993        /* Get task ID. */
    90         ipc_call_t answer;
    91         aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
    92         int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
    93         if (rc != EOK) {
    94                 async_wait_for(req, NULL);
    95                 return rc;
    96         }
    97        
    98         sysarg_t retval;
    99         async_wait_for(req, &retval);
    100         return (int) retval;
     94        async_exch_t *exch = async_exchange_begin(ldr->sess);
     95       
     96        ipc_call_t answer;
     97        aid_t req = async_send_0(exch, LOADER_GET_TASKID, &answer);
     98        sysarg_t rc = async_data_read_start(exch, task_id, sizeof(task_id_t));
     99       
     100        async_exchange_end(exch);
     101       
     102        if (rc != EOK) {
     103                async_wait_for(req, NULL);
     104                return (int) rc;
     105        }
     106       
     107        async_wait_for(req, &rc);
     108        return (int) rc;
    101109}
    102110
     
    112120int loader_set_cwd(loader_t *ldr)
    113121{
    114         char *cwd;
    115         size_t len;
    116 
    117         cwd = (char *) malloc(MAX_PATH_LEN + 1);
     122        char *cwd = (char *) malloc(MAX_PATH_LEN + 1);
    118123        if (!cwd)
    119124                return ENOMEM;
     125       
    120126        if (!getcwd(cwd, MAX_PATH_LEN + 1))
    121                 str_cpy(cwd, MAX_PATH_LEN + 1, "/");
    122         len = str_length(cwd);
    123        
    124         ipc_call_t answer;
    125         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer);
    126         int rc = async_data_write_start(ldr->phone_id, cwd, len);
     127                str_cpy(cwd, MAX_PATH_LEN + 1, "/");
     128       
     129        size_t len = str_length(cwd);
     130       
     131        async_exch_t *exch = async_exchange_begin(ldr->sess);
     132       
     133        ipc_call_t answer;
     134        aid_t req = async_send_0(exch, LOADER_SET_CWD, &answer);
     135        sysarg_t rc = async_data_write_start(exch, cwd, len);
     136       
     137        async_exchange_end(exch);
    127138        free(cwd);
    128         if (rc != EOK) {
    129                 async_wait_for(req, NULL);
    130                 return rc;
    131         }
    132        
    133         sysarg_t retval;
    134         async_wait_for(req, &retval);
    135         return (int) retval;
     139       
     140        if (rc != EOK) {
     141                async_wait_for(req, NULL);
     142                return (int) rc;
     143        }
     144       
     145        async_wait_for(req, &rc);
     146        return (int) rc;
    136147}
    137148
     
    153164        char *pa = absolutize(path, &pa_len);
    154165        if (!pa)
    155                 return 0;
     166                return ENOMEM;
    156167       
    157168        /* Send program pathname */
    158         ipc_call_t answer;
    159         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
    160         int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
    161         if (rc != EOK) {
    162                 free(pa);
    163                 async_wait_for(req, NULL);
    164                 return rc;
    165         }
    166        
     169        async_exch_t *exch = async_exchange_begin(ldr->sess);
     170       
     171        ipc_call_t answer;
     172        aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer);
     173        sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len);
     174       
     175        async_exchange_end(exch);
    167176        free(pa);
    168177       
    169         sysarg_t retval;
    170         async_wait_for(req, &retval);
    171         return (int) retval;
     178        if (rc != EOK) {
     179                async_wait_for(req, NULL);
     180                return (int) rc;
     181        }
     182       
     183        async_wait_for(req, &rc);
     184        return (int) rc;
    172185}
    173186
     
    212225       
    213226        /* Send serialized arguments to the loader */
    214         ipc_call_t answer;
    215         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
    216         sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
    217         if (rc != EOK) {
    218                 async_wait_for(req, NULL);
    219                 return rc;
    220         }
    221        
    222         async_wait_for(req, &rc);
    223         if (rc != EOK)
    224                 return rc;
    225        
    226         /* Free temporary buffer */
     227        async_exch_t *exch = async_exchange_begin(ldr->sess);
     228       
     229        ipc_call_t answer;
     230        aid_t req = async_send_0(exch, LOADER_SET_ARGS, &answer);
     231        sysarg_t rc = async_data_write_start(exch, (void *) arg_buf,
     232            buffer_size);
     233       
     234        async_exchange_end(exch);
    227235        free(arg_buf);
    228236       
    229         return EOK;
     237        if (rc != EOK) {
     238                async_wait_for(req, NULL);
     239                return (int) rc;
     240        }
     241       
     242        async_wait_for(req, &rc);
     243        return (int) rc;
    230244}
    231245
     
    266280       
    267281        /* Send serialized files to the loader */
    268         ipc_call_t answer;
    269         aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
    270         sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf,
     282        async_exch_t *exch = async_exchange_begin(ldr->sess);
     283       
     284        ipc_call_t answer;
     285        aid_t req = async_send_0(exch, LOADER_SET_FILES, &answer);
     286        sysarg_t rc = async_data_write_start(exch, (void *) files_buf,
    271287            count * sizeof(fdi_node_t));
    272         if (rc != EOK) {
    273                 async_wait_for(req, NULL);
    274                 return rc;
    275         }
    276        
    277         async_wait_for(req, &rc);
    278         if (rc != EOK)
    279                 return rc;
    280        
    281         /* Free temporary buffer */
     288       
     289        async_exchange_end(exch);
    282290        free(files_buf);
    283291       
    284         return EOK;
     292        if (rc != EOK) {
     293                async_wait_for(req, NULL);
     294                return (int) rc;
     295        }
     296       
     297        async_wait_for(req, &rc);
     298        return (int) rc;
    285299}
    286300
     
    297311int loader_load_program(loader_t *ldr)
    298312{
    299         return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
     313        async_exch_t *exch = async_exchange_begin(ldr->sess);
     314        int rc = async_req_0_0(exch, LOADER_LOAD);
     315        async_exchange_end(exch);
     316       
     317        return rc;
    300318}
    301319
     
    306324 * the task and its thread is stopped.
    307325 *
    308  * After using this function, no further operations must be performed
    309  * on the loader structure. It should be de-allocated using free().
     326 * After using this function, no further operations can be performed
     327 * on the loader structure and it is deallocated.
    310328 *
    311329 * @param ldr Loader connection structure.
     
    316334int loader_run(loader_t *ldr)
    317335{
    318         int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
     336        async_exch_t *exch = async_exchange_begin(ldr->sess);
     337        int rc = async_req_0_0(exch, LOADER_RUN);
     338        async_exchange_end(exch);
     339       
    319340        if (rc != EOK)
    320341                return rc;
    321342       
    322         async_hangup(ldr->phone_id);
    323         ldr->phone_id = 0;
     343        async_hangup(ldr->sess);
     344        free(ldr);
     345       
    324346        return EOK;
    325347}
     
    327349/** Cancel the loader session.
    328350 *
    329  * Tells the loader not to load any program and terminate.
    330  * After using this function, no further operations must be performed
    331  * on the loader structure. It should be de-allocated using free().
     351 * Tell the loader not to load any program and terminate.
     352 * After using this function, no further operations can be performed
     353 * on the loader structure and it is deallocated.
    332354 *
    333355 * @param ldr Loader connection structure.
     
    338360void loader_abort(loader_t *ldr)
    339361{
    340         async_hangup(ldr->phone_id);
    341         ldr->phone_id = 0;
     362        async_hangup(ldr->sess);
     363        free(ldr);
    342364}
    343365
  • uspace/lib/c/generic/net/icmp_api.c

    r764d71e r79ae36dd  
    4242#include <net/ip_codes.h>
    4343#include <async.h>
     44#include <async_obsolete.h>
    4445#include <sys/types.h>
    4546#include <sys/time.h>
     
    8384                return EINVAL;
    8485
    85         message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
     86        message_id = async_obsolete_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
    8687            tos, (sysarg_t) dont_fragment, NULL);
    8788
    8889        /* Send the address */
    89         async_data_write_start(icmp_phone, addr, (size_t) addrlen);
     90        async_obsolete_data_write_start(icmp_phone, addr, (size_t) addrlen);
    9091
    9192        async_wait_for(message_id, &result);
  • uspace/lib/c/generic/net/modules.c

    r764d71e r79ae36dd  
    4040
    4141#include <async.h>
     42#include <async_obsolete.h>
    4243#include <malloc.h>
    4344#include <errno.h>
     
    4546#include <ipc/services.h>
    4647#include <net/modules.h>
     48#include <ns.h>
     49#include <ns_obsolete.h>
    4750
    4851/** The time between connect requests in microseconds. */
    49 #define MODULE_WAIT_TIME        (10 * 1000)
     52#define MODULE_WAIT_TIME  (10 * 1000)
    5053
    5154/** Answer a call.
     
    138141        if (phone >= 0) {
    139142                /* Request the bidirectional connection */
    140                 int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
     143                int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
    141144                if (rc != EOK) {
    142                         async_hangup(phone);
     145                        async_obsolete_hangup(phone);
    143146                        return rc;
    144147                }
     
    172175        /* If no timeout is set */
    173176        if (timeout <= 0)
    174                 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
    175 
     177                return service_obsolete_connect_blocking(need, 0, 0);
     178       
    176179        while (true) {
    177                 phone = async_connect_me_to(PHONE_NS, need, 0, 0);
     180                phone = service_obsolete_connect(need, 0, 0);
    178181                if ((phone >= 0) || (phone != ENOENT))
    179182                        return phone;
  • uspace/lib/c/generic/net/socket_client.c

    r764d71e r79ae36dd  
    3939#include <assert.h>
    4040#include <async.h>
     41#include <async_obsolete.h>
    4142#include <fibril_synch.h>
    4243#include <stdint.h>
     
    472473        }
    473474
    474         rc = (int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
     475        rc = (int) async_obsolete_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
    475476            &fragment_size, &header_size);
    476477        if (rc != EOK) {
     
    493494                dyn_fifo_destroy(&socket->accepted);
    494495                free(socket);
    495                 async_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
     496                async_obsolete_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
    496497                    service);
    497498                return rc;
     
    538539
    539540        /* Request the message */
    540         message_id = async_send_3(socket->phone, message,
     541        message_id = async_obsolete_send_3(socket->phone, message,
    541542            (sysarg_t) socket->socket_id, arg2, socket->service, NULL);
    542543        /* Send the address */
    543         async_data_write_start(socket->phone, data, datalength);
     544        async_obsolete_data_write_start(socket->phone, data, datalength);
    544545
    545546        fibril_rwlock_read_unlock(&socket_globals.lock);
     
    598599
    599600        /* Request listen backlog change */
    600         result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN,
     601        result = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_LISTEN,
    601602            (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service);
    602603
     
    681682
    682683        /* Request accept */
    683         message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT,
     684        message_id = async_obsolete_send_5(socket->phone, NET_SOCKET_ACCEPT,
    684685            (sysarg_t) socket->socket_id, 0, socket->service, 0,
    685686            new_socket->socket_id, &answer);
    686687
    687688        /* Read address */
    688         async_data_read_start(socket->phone, cliaddr, *addrlen);
     689        async_obsolete_data_read_start(socket->phone, cliaddr, *addrlen);
    689690        fibril_rwlock_write_unlock(&socket_globals.lock);
    690691        async_wait_for(message_id, &ipc_result);
     
    780781
    781782        /* Request close */
    782         rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE,
     783        rc = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_CLOSE,
    783784            (sysarg_t) socket->socket_id, 0, socket->service);
    784785        if (rc != EOK) {
     
    853854
    854855        /* Request send */
    855         message_id = async_send_5(socket->phone, message,
     856        message_id = async_obsolete_send_5(socket->phone, message,
    856857            (sysarg_t) socket->socket_id,
    857858            (fragments == 1 ? datalength : socket->data_fragment_size),
     
    860861        /* Send the address if given */
    861862        if (!toaddr ||
    862             (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
     863            (async_obsolete_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
    863864                if (fragments == 1) {
    864865                        /* Send all if only one fragment */
    865                         async_data_write_start(socket->phone, data, datalength);
     866                        async_obsolete_data_write_start(socket->phone, data, datalength);
    866867                } else {
    867868                        /* Send the first fragment */
    868                         async_data_write_start(socket->phone, data,
     869                        async_obsolete_data_write_start(socket->phone, data,
    869870                            socket->data_fragment_size - socket->header_size);
    870871                        data = ((const uint8_t *) data) +
     
    873874                        /* Send the middle fragments */
    874875                        while (--fragments > 1) {
    875                                 async_data_write_start(socket->phone, data,
     876                                async_obsolete_data_write_start(socket->phone, data,
    876877                                    socket->data_fragment_size);
    877878                                data = ((const uint8_t *) data) +
     
    880881
    881882                        /* Send the last fragment */
    882                         async_data_write_start(socket->phone, data,
     883                        async_obsolete_data_write_start(socket->phone, data,
    883884                            (datalength + socket->header_size) %
    884885                            socket->data_fragment_size);
     
    10381039
    10391040                /* Request packet data */
    1040                 message_id = async_send_4(socket->phone, message,
     1041                message_id = async_obsolete_send_4(socket->phone, message,
    10411042                    (sysarg_t) socket->socket_id, 0, socket->service,
    10421043                    (sysarg_t) flags, &answer);
     
    10441045                /* Read the address if desired */
    10451046                if(!fromaddr ||
    1046                     (async_data_read_start(socket->phone, fromaddr,
     1047                    (async_obsolete_data_read_start(socket->phone, fromaddr,
    10471048                    *addrlen) == EOK)) {
    10481049                        /* Read the fragment lengths */
    1049                         if (async_data_read_start(socket->phone, lengths,
     1050                        if (async_obsolete_data_read_start(socket->phone, lengths,
    10501051                            sizeof(int) * (fragments + 1)) == EOK) {
    10511052                                if (lengths[fragments] <= datalength) {
     
    10541055                                        for (index = 0; index < fragments;
    10551056                                            ++index) {
    1056                                                 async_data_read_start(
     1057                                                async_obsolete_data_read_start(
    10571058                                                    socket->phone, data,
    10581059                                                    lengths[index]);
     
    10671068        } else { /* fragments == 1 */
    10681069                /* Request packet data */
    1069                 message_id = async_send_4(socket->phone, message,
     1070                message_id = async_obsolete_send_4(socket->phone, message,
    10701071                    (sysarg_t) socket->socket_id, 0, socket->service,
    10711072                    (sysarg_t) flags, &answer);
     
    10731074                /* Read the address if desired */
    10741075                if (!fromaddr ||
    1075                     (async_data_read_start(socket->phone, fromaddr,
     1076                    (async_obsolete_data_read_start(socket->phone, fromaddr,
    10761077                        *addrlen) == EOK)) {
    10771078                        /* Read all if only one fragment */
    1078                         async_data_read_start(socket->phone, data, datalength);
     1079                        async_obsolete_data_read_start(socket->phone, data, datalength);
    10791080                }
    10801081        }
     
    11901191
    11911192        /* Request option value */
    1192         message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
     1193        message_id = async_obsolete_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
    11931194            (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service,
    11941195            NULL);
    11951196
    11961197        /* Read the length */
    1197         if (async_data_read_start(socket->phone, optlen,
     1198        if (async_obsolete_data_read_start(socket->phone, optlen,
    11981199            sizeof(*optlen)) == EOK) {
    11991200                /* Read the value */
    1200                 async_data_read_start(socket->phone, value, *optlen);
     1201                async_obsolete_data_read_start(socket->phone, value, *optlen);
    12011202        }
    12021203
  • uspace/lib/c/generic/ns_obsolete.c

    r764d71e r79ae36dd  
    3434
    3535#include <async.h>
    36 #include <ipc/ns.h>
     36#include <async_obsolete.h>
     37#include <ns_obsolete.h>
     38#include <kernel/ipc/ipc_methods.h>
    3739
    38 int service_register(sysarg_t service)
     40int service_obsolete_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
    3941{
    40         return async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
     42        return async_obsolete_connect_me_to(PHONE_NS, service, arg2, arg3);
    4143}
    4244
    43 int service_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
     45int service_obsolete_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
    4446{
    45         return async_connect_me_to(PHONE_NS, service, arg2, arg3);
    46 }
    47 
    48 int service_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
    49 {
    50         return async_connect_me_to_blocking(PHONE_NS, service, arg2, arg3);
     47        return async_obsolete_connect_me_to_blocking(PHONE_NS, service, arg2, arg3);
    5148}
    5249
  • uspace/lib/c/generic/private/async.h

    r764d71e r79ae36dd  
    7979} awaiter_t;
    8080
     81/** Message data */
     82typedef struct {
     83        awaiter_t wdata;
     84       
     85        /** If reply was received. */
     86        bool done;
     87       
     88        /** Pointer to where the answer data is stored. */
     89        ipc_call_t *dataptr;
     90       
     91        sysarg_t retval;
     92} amsg_t;
     93
    8194extern void __async_init(void);
    8295extern void async_insert_timeout(awaiter_t *);
     96extern void reply_received(void *, int, ipc_call_t *);
    8397
    8498#endif
  • uspace/lib/c/generic/private/ns.h

    r764d71e r79ae36dd  
    3333 */
    3434
    35 #ifndef LIBC_PRIVATE_ASYNC_SESS_H_
    36 #define LIBC_PRIVATE_ASYNC_SESS_H_
     35#ifndef LIBC_PRIVATE_NS_H_
     36#define LIBC_PRIVATE_NS_H_
    3737
    38 extern void __async_sess_init(void);
     38#include <async.h>
     39
     40extern async_sess_t *session_ns;
    3941
    4042#endif
  • uspace/lib/c/generic/str_error.c

    r764d71e r79ae36dd  
    7070       
    7171        /* Ad hoc descriptions of error codes interesting for USB. */
     72        // FIXME: integrate these as first-class error values
    7273        switch (e) {
    7374                case EBADCHECKSUM:
  • uspace/lib/c/generic/task.c

    r764d71e r79ae36dd  
    3535
    3636#include <task.h>
    37 #include <libc.h>
    38 #include <stdlib.h>
    39 #include <errno.h>
    4037#include <loader/loader.h>
    4138#include <stdarg.h>
     
    4340#include <ipc/ns.h>
    4441#include <macros.h>
     42#include <assert.h>
    4543#include <async.h>
     44#include <errno.h>
     45#include <malloc.h>
     46#include <libc.h>
     47#include "private/ns.h"
    4648
    4749task_id_t task_get_id(void)
     
    6870int task_set_name(const char *name)
    6971{
     72        assert(name);
     73       
    7074        return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name));
    7175}
     
    8892 * loader API. Arguments are passed as a null-terminated array of strings.
    8993 *
    90  * @param id    If not NULL, the ID of the task is stored here on success.
    91  * @param path  Pathname of the binary to execute.
    92  * @param argv  Command-line arguments.
    93  *
    94  * @return      Zero on success or negative error code.
     94 * @param id   If not NULL, the ID of the task is stored here on success.
     95 * @param path Pathname of the binary to execute.
     96 * @param argv Command-line arguments.
     97 *
     98 * @return Zero on success or negative error code.
     99 *
    95100 */
    96101int task_spawnv(task_id_t *id, const char *path, const char *const args[])
    97102{
    98         loader_t *ldr;
    99         task_id_t task_id;
    100         int rc;
    101 
    102103        /* Connect to a program loader. */
    103         ldr = loader_connect();
     104        loader_t *ldr = loader_connect();
    104105        if (ldr == NULL)
    105106                return EREFUSED;
    106107       
    107108        /* Get task ID. */
    108         rc = loader_get_task_id(ldr, &task_id);
     109        task_id_t task_id;
     110        int rc = loader_get_task_id(ldr, &task_id);
    109111        if (rc != EOK)
    110112                goto error;
     
    163165       
    164166        /* Success */
    165         free(ldr);
    166        
    167167        if (id != NULL)
    168168                *id = task_id;
     
    182182 * loader API. Arguments are passed as a null-terminated list of arguments.
    183183 *
    184  * @param id    If not NULL, the ID of the task is stored here on success.
    185  * @param path  Pathname of the binary to execute.
    186  * @param ...   Command-line arguments.
    187  *
    188  * @return      Zero on success or negative error code.
     184 * @param id   If not NULL, the ID of the task is stored here on success.
     185 * @param path Pathname of the binary to execute.
     186 * @param ...  Command-line arguments.
     187 *
     188 * @return Zero on success or negative error code.
     189 *
    189190 */
    190191int task_spawnl(task_id_t *task_id, const char *path, ...)
    191192{
     193        /* Count the number of arguments. */
     194       
    192195        va_list ap;
    193         int rc, cnt;
    194196        const char *arg;
    195197        const char **arglist;
    196 
    197         /* Count the number of arguments. */
    198         cnt = 0;
     198        int cnt = 0;
     199       
    199200        va_start(ap, path);
    200201        do {
     
    203204        } while (arg != NULL);
    204205        va_end(ap);
    205 
     206       
    206207        /* Allocate argument list. */
    207208        arglist = malloc(cnt * sizeof(const char *));
    208209        if (arglist == NULL)
    209210                return ENOMEM;
    210 
     211       
    211212        /* Fill in arguments. */
    212213        cnt = 0;
     
    217218        } while (arg != NULL);
    218219        va_end(ap);
    219 
     220       
    220221        /* Spawn task. */
    221         rc = task_spawnv(task_id, path, arglist);
    222 
     222        int rc = task_spawnv(task_id, path, arglist);
     223       
    223224        /* Free argument list. */
    224225        free(arglist);
     
    228229int task_wait(task_id_t id, task_exit_t *texit, int *retval)
    229230{
     231        assert(texit);
     232        assert(retval);
     233       
     234        async_exch_t *exch = async_exchange_begin(session_ns);
    230235        sysarg_t te, rv;
    231         int rc;
    232 
    233         rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id),
     236        int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id),
    234237            UPPER32(id), &te, &rv);
     238        async_exchange_end(exch);
     239       
    235240        *texit = te;
    236241        *retval = rv;
    237 
     242       
    238243        return rc;
    239244}
     
    241246int task_retval(int val)
    242247{
    243         return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val);
     248        async_exch_t *exch = async_exchange_begin(session_ns);
     249        int rc = (int) async_req_1_0(exch, NS_RETVAL, val);
     250        async_exchange_end(exch);
     251       
     252        return rc;
    244253}
    245254
  • uspace/lib/c/generic/udebug.c

    r764d71e r79ae36dd  
    3535#include <udebug.h>
    3636#include <sys/types.h>
     37#include <kernel/ipc/ipc_methods.h>
    3738#include <async.h>
    3839
    39 int udebug_begin(int phoneid)
     40int udebug_begin(async_sess_t *sess)
    4041{
    41         return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_BEGIN);
     42        async_exch_t *exch = async_exchange_begin(sess);
     43        return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_BEGIN);
    4244}
    4345
    44 int udebug_end(int phoneid)
     46int udebug_end(async_sess_t *sess)
    4547{
    46         return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_END);
     48        async_exch_t *exch = async_exchange_begin(sess);
     49        return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_END);
    4750}
    4851
    49 int udebug_set_evmask(int phoneid, udebug_evmask_t mask)
     52int udebug_set_evmask(async_sess_t *sess, udebug_evmask_t mask)
    5053{
    51         return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_SET_EVMASK,
    52                 mask);
     54        async_exch_t *exch = async_exchange_begin(sess);
     55        return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_SET_EVMASK, mask);
    5356}
    5457
    55 int udebug_thread_read(int phoneid, void *buffer, size_t n,
    56         size_t *copied, size_t *needed)
     58int udebug_thread_read(async_sess_t *sess, void *buffer, size_t n,
     59    size_t *copied, size_t *needed)
    5760{
    5861        sysarg_t a_copied, a_needed;
    59         int rc;
    60 
    61         rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,
    62                 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
    63 
    64         *copied = (size_t)a_copied;
    65         *needed = (size_t)a_needed;
    66 
     62       
     63        async_exch_t *exch = async_exchange_begin(sess);
     64        int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_THREAD_READ,
     65            (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
     66       
     67        *copied = (size_t) a_copied;
     68        *needed = (size_t) a_needed;
     69       
    6770        return rc;
    6871}
    6972
    70 int udebug_name_read(int phoneid, void *buffer, size_t n,
    71         size_t *copied, size_t *needed)
     73int udebug_name_read(async_sess_t *sess, void *buffer, size_t n,
     74    size_t *copied, size_t *needed)
    7275{
    7376        sysarg_t a_copied, a_needed;
    74         int rc;
    75 
    76         rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,
    77                 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
    78 
    79         *copied = (size_t)a_copied;
    80         *needed = (size_t)a_needed;
    81 
     77       
     78        async_exch_t *exch = async_exchange_begin(sess);
     79        int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_NAME_READ,
     80            (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
     81       
     82        *copied = (size_t) a_copied;
     83        *needed = (size_t) a_needed;
     84       
    8285        return rc;
    8386}
    8487
    85 int udebug_areas_read(int phoneid, void *buffer, size_t n,
    86         size_t *copied, size_t *needed)
     88int udebug_areas_read(async_sess_t *sess, void *buffer, size_t n,
     89    size_t *copied, size_t *needed)
    8790{
    8891        sysarg_t a_copied, a_needed;
    89         int rc;
    90 
    91         rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,
    92                 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
    93 
    94         *copied = (size_t)a_copied;
    95         *needed = (size_t)a_needed;
    96 
     92       
     93        async_exch_t *exch = async_exchange_begin(sess);
     94        int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_AREAS_READ,
     95            (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
     96       
     97        *copied = (size_t) a_copied;
     98        *needed = (size_t) a_needed;
     99       
    97100        return rc;
    98101}
    99102
    100 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
     103int udebug_mem_read(async_sess_t *sess, void *buffer, uintptr_t addr, size_t n)
    101104{
    102         return async_req_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_MEM_READ,
    103             (sysarg_t)buffer, addr, n);
     105        async_exch_t *exch = async_exchange_begin(sess);
     106        return async_req_4_0(exch, IPC_M_DEBUG, UDEBUG_M_MEM_READ,
     107            (sysarg_t) buffer, addr, n);
    104108}
    105109
    106 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer)
     110int udebug_args_read(async_sess_t *sess, thash_t tid, sysarg_t *buffer)
    107111{
    108         return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ,
    109             tid, (sysarg_t)buffer);
     112        async_exch_t *exch = async_exchange_begin(sess);
     113        return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_ARGS_READ,
     114            tid, (sysarg_t) buffer);
    110115}
    111116
    112 int udebug_regs_read(int phoneid, thash_t tid, void *buffer)
     117int udebug_regs_read(async_sess_t *sess, thash_t tid, void *buffer)
    113118{
    114         return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ,
    115             tid, (sysarg_t)buffer);
     119        async_exch_t *exch = async_exchange_begin(sess);
     120        return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_REGS_READ,
     121            tid, (sysarg_t) buffer);
    116122}
    117123
    118 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
     124int udebug_go(async_sess_t *sess, thash_t tid, udebug_event_t *ev_type,
    119125    sysarg_t *val0, sysarg_t *val1)
    120126{
    121127        sysarg_t a_ev_type;
    122         int rc;
    123 
    124         rc =  async_req_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,
     128       
     129        async_exch_t *exch = async_exchange_begin(sess);
     130        int rc = async_req_2_3(exch, IPC_M_DEBUG, UDEBUG_M_GO,
    125131            tid, &a_ev_type, val0, val1);
    126 
     132       
    127133        *ev_type = a_ev_type;
    128134        return rc;
    129135}
    130136
    131 int udebug_stop(int phoneid, thash_t tid)
     137int udebug_stop(async_sess_t *sess, thash_t tid)
    132138{
    133         return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_STOP,
    134             tid);
     139        async_exch_t *exch = async_exchange_begin(sess);
     140        return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_STOP, tid);
    135141}
    136142
  • uspace/lib/c/generic/vfs/vfs.c

    r764d71e r79ae36dd  
    3333 */
    3434
     35#include <vfs/canonify.h>
    3536#include <vfs/vfs.h>
    36 #include <vfs/canonify.h>
     37#include <vfs/vfs_sess.h>
    3738#include <macros.h>
    3839#include <stdlib.h>
     
    4445#include <sys/types.h>
    4546#include <ipc/services.h>
    46 #include <ipc/ns.h>
     47#include <ns.h>
    4748#include <async.h>
    4849#include <fibril_synch.h>
     
    5455#include <ipc/devmap.h>
    5556
    56 static async_sess_t vfs_session;
    57 
    58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    59 static int vfs_phone = -1;
     57static FIBRIL_MUTEX_INITIALIZE(vfs_mutex);
     58static async_sess_t *vfs_sess = NULL;
    6059
    6160static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
     
    6564static size_t cwd_size = 0;
    6665
     66/** Start an async exchange on the VFS session.
     67 *
     68 * @return New exchange.
     69 *
     70 */
     71static async_exch_t *vfs_exchange_begin(void)
     72{
     73        fibril_mutex_lock(&vfs_mutex);
     74       
     75        while (vfs_sess == NULL)
     76                vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS,
     77                    0, 0);
     78       
     79        fibril_mutex_unlock(&vfs_mutex);
     80       
     81        return async_exchange_begin(vfs_sess);
     82}
     83
     84/** Finish an async exchange on the VFS session.
     85 *
     86 * @param exch Exchange to be finished.
     87 *
     88 */
     89static void vfs_exchange_end(async_exch_t *exch)
     90{
     91        async_exchange_end(exch);
     92}
     93
    6794char *absolutize(const char *path, size_t *retlen)
    6895{
    6996        char *ncwd_path;
    7097        char *ncwd_path_nc;
    71         size_t total_size;
    7298
    7399        fibril_mutex_lock(&cwd_mutex);
     
    78104                        return NULL;
    79105                }
    80                 total_size = cwd_size + 1 + size + 1;
    81                 ncwd_path_nc = malloc(total_size);
     106                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    82107                if (!ncwd_path_nc) {
    83108                        fibril_mutex_unlock(&cwd_mutex);
    84109                        return NULL;
    85110                }
    86                 str_cpy(ncwd_path_nc, total_size, cwd_path);
     111                str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
    87112                ncwd_path_nc[cwd_size] = '/';
    88113                ncwd_path_nc[cwd_size + 1] = '\0';
    89114        } else {
    90                 total_size = size + 1;
    91                 ncwd_path_nc = malloc(total_size);
     115                ncwd_path_nc = malloc(size + 1);
    92116                if (!ncwd_path_nc) {
    93117                        fibril_mutex_unlock(&cwd_mutex);
     
    96120                ncwd_path_nc[0] = '\0';
    97121        }
    98         str_append(ncwd_path_nc, total_size, path);
     122        str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
    99123        ncwd_path = canonify(ncwd_path_nc, retlen);
    100124        if (!ncwd_path) {
     
    118142}
    119143
    120 /** Connect to VFS service and create session. */
    121 static void vfs_connect(void)
    122 {
    123         while (vfs_phone < 0)
    124                 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    125        
    126         async_session_create(&vfs_session, vfs_phone, 0);
    127 }
    128 
    129 /** Start an async exchange on the VFS session.
    130  *
    131  * @return              New phone to be used during the exchange.
    132  */
    133 static int vfs_exchange_begin(void)
    134 {
    135         fibril_mutex_lock(&vfs_phone_mutex);
    136         if (vfs_phone < 0)
    137                 vfs_connect();
    138         fibril_mutex_unlock(&vfs_phone_mutex);
    139 
    140         return async_exchange_begin(&vfs_session);
    141 }
    142 
    143 /** End an async exchange on the VFS session.
    144  *
    145  * @param phone         Phone used during the exchange.
    146  */
    147 static void vfs_exchange_end(int phone)
    148 {
    149         async_exchange_end(&vfs_session, phone);
    150 }
    151 
    152144int mount(const char *fs_name, const char *mp, const char *fqdn,
    153145    const char *opts, unsigned int flags)
     
    186178        }
    187179       
    188         int vfs_phone = vfs_exchange_begin();
     180        async_exch_t *exch = vfs_exchange_begin();
    189181
    190182        sysarg_t rc_orig;
    191         aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    192         sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    193         if (rc != EOK) {
    194                 vfs_exchange_end(vfs_phone);
     183        aid_t req = async_send_2(exch, VFS_IN_MOUNT, devmap_handle, flags, NULL);
     184        sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size);
     185        if (rc != EOK) {
     186                vfs_exchange_end(exch);
    195187                free(mpa);
    196188                async_wait_for(req, &rc_orig);
     
    205197        }
    206198       
    207         rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    208         if (rc != EOK) {
    209                 vfs_exchange_end(vfs_phone);
     199        rc = async_data_write_start(exch, (void *) opts, str_size(opts));
     200        if (rc != EOK) {
     201                vfs_exchange_end(exch);
    210202                free(mpa);
    211203                async_wait_for(req, &rc_orig);
     
    220212        }
    221213       
    222         rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    223         if (rc != EOK) {
    224                 vfs_exchange_end(vfs_phone);
     214        rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
     215        if (rc != EOK) {
     216                vfs_exchange_end(exch);
    225217                free(mpa);
    226218                async_wait_for(req, &rc_orig);
     
    236228       
    237229        /* Ask VFS whether it likes fs_name. */
    238         rc = async_req_0_0(vfs_phone, IPC_M_PING);
    239         if (rc != EOK) {
    240                 vfs_exchange_end(vfs_phone);
     230        rc = async_req_0_0(exch, VFS_IN_PING);
     231        if (rc != EOK) {
     232                vfs_exchange_end(exch);
    241233                free(mpa);
    242234                async_wait_for(req, &rc_orig);
     
    251243        }
    252244       
    253         vfs_exchange_end(vfs_phone);
     245        vfs_exchange_end(exch);
    254246        free(mpa);
    255247        async_wait_for(req, &rc);
     
    273265                return ENOMEM;
    274266       
    275         int vfs_phone = vfs_exchange_begin();
    276        
    277         req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    278         rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    279         if (rc != EOK) {
    280                 vfs_exchange_end(vfs_phone);
     267        async_exch_t *exch = vfs_exchange_begin();
     268       
     269        req = async_send_0(exch, VFS_IN_UNMOUNT, NULL);
     270        rc = async_data_write_start(exch, (void *) mpa, mpa_size);
     271        if (rc != EOK) {
     272                vfs_exchange_end(exch);
    281273                free(mpa);
    282274                async_wait_for(req, &rc_orig);
     
    288280       
    289281
    290         vfs_exchange_end(vfs_phone);
     282        vfs_exchange_end(exch);
    291283        free(mpa);
    292284        async_wait_for(req, &rc);
     
    297289static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    298290{
    299         int vfs_phone = vfs_exchange_begin();
     291        async_exch_t *exch = vfs_exchange_begin();
    300292       
    301293        ipc_call_t answer;
    302         aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
    303         sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
    304        
    305         if (rc != EOK) {
    306                 vfs_exchange_end(vfs_phone);
     294        aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer);
     295        sysarg_t rc = async_data_write_start(exch, abs, abs_size);
     296       
     297        if (rc != EOK) {
     298                vfs_exchange_end(exch);
    307299
    308300                sysarg_t rc_orig;
     
    315307        }
    316308       
    317         vfs_exchange_end(vfs_phone);
     309        vfs_exchange_end(exch);
    318310        async_wait_for(req, &rc);
    319311       
     
    339331int open_node(fdi_node_t *node, int oflag)
    340332{
    341         int vfs_phone = vfs_exchange_begin();
     333        async_exch_t *exch = vfs_exchange_begin();
    342334       
    343335        ipc_call_t answer;
    344         aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
     336        aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,
    345337            node->devmap_handle, node->index, oflag, &answer);
    346338       
    347         vfs_exchange_end(vfs_phone);
     339        vfs_exchange_end(exch);
    348340
    349341        sysarg_t rc;
     
    360352        sysarg_t rc;
    361353       
    362         int vfs_phone = vfs_exchange_begin();
    363        
    364         rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    365        
    366         vfs_exchange_end(vfs_phone);
    367        
    368         return (int)rc;
     354        async_exch_t *exch = vfs_exchange_begin();
     355        rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes);
     356        vfs_exchange_end(exch);
     357       
     358        return (int) rc;
    369359}
    370360
     
    374364        ipc_call_t answer;
    375365        aid_t req;
    376 
    377         int vfs_phone = vfs_exchange_begin();
    378        
    379         req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    380         rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte,
    381             IPC_XF_RESTRICT);
    382         if (rc != EOK) {
    383                 vfs_exchange_end(vfs_phone);
     366       
     367        async_exch_t *exch = vfs_exchange_begin();
     368       
     369        req = async_send_1(exch, VFS_IN_READ, fildes, &answer);
     370        rc = async_data_read_start(exch, (void *)buf, nbyte);
     371        if (rc != EOK) {
     372                vfs_exchange_end(exch);
    384373
    385374                sysarg_t rc_orig;
     
    391380                        return (ssize_t) rc_orig;
    392381        }
    393         vfs_exchange_end(vfs_phone);
     382        vfs_exchange_end(exch);
    394383        async_wait_for(req, &rc);
    395384        if (rc == EOK)
     
    404393        ipc_call_t answer;
    405394        aid_t req;
    406 
    407         int vfs_phone = vfs_exchange_begin();
    408        
    409         req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    410         rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte,
    411             IPC_XF_RESTRICT);
    412         if (rc != EOK) {
    413                 vfs_exchange_end(vfs_phone);
     395       
     396        async_exch_t *exch = vfs_exchange_begin();
     397       
     398        req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer);
     399        rc = async_data_write_start(exch, (void *)buf, nbyte);
     400        if (rc != EOK) {
     401                vfs_exchange_end(exch);
    414402
    415403                sysarg_t rc_orig;
     
    421409                        return (ssize_t) rc_orig;
    422410        }
    423         vfs_exchange_end(vfs_phone);
     411        vfs_exchange_end(exch);
    424412        async_wait_for(req, &rc);
    425413        if (rc == EOK)
     
    431419int fsync(int fildes)
    432420{
    433         int vfs_phone = vfs_exchange_begin();
    434        
    435         sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    436        
    437         vfs_exchange_end(vfs_phone);
     421        async_exch_t *exch = vfs_exchange_begin();
     422        sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
     423        vfs_exchange_end(exch);
    438424       
    439425        return (int) rc;
     
    442428off64_t lseek(int fildes, off64_t offset, int whence)
    443429{
    444         int vfs_phone = vfs_exchange_begin();
     430        async_exch_t *exch = vfs_exchange_begin();
    445431       
    446432        sysarg_t newoff_lo;
    447433        sysarg_t newoff_hi;
    448         sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     434        sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
    449435            LOWER32(offset), UPPER32(offset), whence,
    450436            &newoff_lo, &newoff_hi);
    451437       
    452         vfs_exchange_end(vfs_phone);
     438        vfs_exchange_end(exch);
    453439       
    454440        if (rc != EOK)
     
    462448        sysarg_t rc;
    463449       
    464         int vfs_phone = vfs_exchange_begin();
    465        
    466         rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     450        async_exch_t *exch = vfs_exchange_begin();
     451        rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
    467452            LOWER32(length), UPPER32(length));
    468         vfs_exchange_end(vfs_phone);
     453        vfs_exchange_end(exch);
    469454       
    470455        return (int) rc;
     
    475460        sysarg_t rc;
    476461        aid_t req;
    477 
    478         int vfs_phone = vfs_exchange_begin();
    479        
    480         req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    481         rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    482         if (rc != EOK) {
    483                 vfs_exchange_end(vfs_phone);
     462       
     463        async_exch_t *exch = vfs_exchange_begin();
     464       
     465        req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
     466        rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
     467        if (rc != EOK) {
     468                vfs_exchange_end(exch);
    484469
    485470                sysarg_t rc_orig;
     
    491476                        return (ssize_t) rc_orig;
    492477        }
    493         vfs_exchange_end(vfs_phone);
     478        vfs_exchange_end(exch);
    494479        async_wait_for(req, &rc);
    495480
     
    508493                return ENOMEM;
    509494       
    510         int vfs_phone = vfs_exchange_begin();
    511        
    512         req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    513         rc = async_data_write_start(vfs_phone, pa, pa_size);
    514         if (rc != EOK) {
    515                 vfs_exchange_end(vfs_phone);
     495        async_exch_t *exch = vfs_exchange_begin();
     496       
     497        req = async_send_0(exch, VFS_IN_STAT, NULL);
     498        rc = async_data_write_start(exch, pa, pa_size);
     499        if (rc != EOK) {
     500                vfs_exchange_end(exch);
    516501                free(pa);
    517502                async_wait_for(req, &rc_orig);
     
    521506                        return (int) rc_orig;
    522507        }
    523         rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    524         if (rc != EOK) {
    525                 vfs_exchange_end(vfs_phone);
     508        rc = async_data_read_start(exch, stat, sizeof(struct stat));
     509        if (rc != EOK) {
     510                vfs_exchange_end(exch);
    526511                free(pa);
    527512                async_wait_for(req, &rc_orig);
     
    531516                        return (int) rc_orig;
    532517        }
    533         vfs_exchange_end(vfs_phone);
     518        vfs_exchange_end(exch);
    534519        free(pa);
    535520        async_wait_for(req, &rc);
     
    592577                return ENOMEM;
    593578       
    594         int vfs_phone = vfs_exchange_begin();
    595        
    596         req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    597         rc = async_data_write_start(vfs_phone, pa, pa_size);
    598         if (rc != EOK) {
    599                 vfs_exchange_end(vfs_phone);
     579        async_exch_t *exch = vfs_exchange_begin();
     580       
     581        req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
     582        rc = async_data_write_start(exch, pa, pa_size);
     583        if (rc != EOK) {
     584                vfs_exchange_end(exch);
    600585                free(pa);
    601586
     
    608593                        return (int) rc_orig;
    609594        }
    610         vfs_exchange_end(vfs_phone);
     595        vfs_exchange_end(exch);
    611596        free(pa);
    612597        async_wait_for(req, &rc);
     
    623608        if (!pa)
    624609                return ENOMEM;
    625 
    626         int vfs_phone = vfs_exchange_begin();
    627        
    628         req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    629         rc = async_data_write_start(vfs_phone, pa, pa_size);
    630         if (rc != EOK) {
    631                 vfs_exchange_end(vfs_phone);
     610       
     611        async_exch_t *exch = vfs_exchange_begin();
     612       
     613        req = async_send_0(exch, VFS_IN_UNLINK, NULL);
     614        rc = async_data_write_start(exch, pa, pa_size);
     615        if (rc != EOK) {
     616                vfs_exchange_end(exch);
    632617                free(pa);
    633618
     
    640625                        return (int) rc_orig;
    641626        }
    642         vfs_exchange_end(vfs_phone);
     627        vfs_exchange_end(exch);
    643628        free(pa);
    644629        async_wait_for(req, &rc);
     
    673658                return ENOMEM;
    674659        }
    675 
    676         int vfs_phone = vfs_exchange_begin();
    677        
    678         req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    679         rc = async_data_write_start(vfs_phone, olda, olda_size);
    680         if (rc != EOK) {
    681                 vfs_exchange_end(vfs_phone);
     660       
     661        async_exch_t *exch = vfs_exchange_begin();
     662       
     663        req = async_send_0(exch, VFS_IN_RENAME, NULL);
     664        rc = async_data_write_start(exch, olda, olda_size);
     665        if (rc != EOK) {
     666                vfs_exchange_end(exch);
    682667                free(olda);
    683668                free(newa);
     
    688673                        return (int) rc_orig;
    689674        }
    690         rc = async_data_write_start(vfs_phone, newa, newa_size);
    691         if (rc != EOK) {
    692                 vfs_exchange_end(vfs_phone);
     675        rc = async_data_write_start(exch, newa, newa_size);
     676        if (rc != EOK) {
     677                vfs_exchange_end(exch);
    693678                free(olda);
    694679                free(newa);
     
    699684                        return (int) rc_orig;
    700685        }
    701         vfs_exchange_end(vfs_phone);
     686        vfs_exchange_end(exch);
    702687        free(olda);
    703688        free(newa);
     
    755740}
    756741
    757 int fd_phone(int fildes)
     742async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
    758743{
    759744        struct stat stat;
    760        
    761745        int rc = fstat(fildes, &stat);
    762         if (rc != 0)
    763                 return rc;
    764        
    765         if (!stat.device)
    766                 return -1;
    767        
    768         return devmap_device_connect(stat.device, 0);
     746        if (rc != 0) {
     747                errno = rc;
     748                return NULL;
     749        }
     750       
     751        if (!stat.device) {
     752                errno = ENOENT;
     753                return NULL;
     754        }
     755       
     756        return devmap_device_connect(mgmt, stat.device, 0);
    769757}
    770758
     
    772760{
    773761        struct stat stat;
    774         int rc;
    775 
    776         rc = fstat(fildes, &stat);
     762        int rc = fstat(fildes, &stat);
    777763       
    778764        if (rc == EOK) {
     
    787773int dup2(int oldfd, int newfd)
    788774{
    789         int vfs_phone = vfs_exchange_begin();
     775        async_exch_t *exch = vfs_exchange_begin();
    790776       
    791777        sysarg_t ret;
    792         sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    793        
    794         vfs_exchange_end(vfs_phone);
     778        sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
     779       
     780        vfs_exchange_end(exch);
    795781       
    796782        if (rc == EOK)
  • uspace/lib/c/include/async.h

    r764d71e r79ae36dd  
    4141
    4242#include <ipc/common.h>
    43 #include <async_sess.h>
    4443#include <fibril.h>
     44#include <fibril_synch.h>
    4545#include <sys/time.h>
    4646#include <atomic.h>
     
    5555typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *);
    5656
     57/** Exchange management style
     58 *
     59 */
     60typedef enum {
     61        /** No explicit exchange management
     62         *
     63         * Suitable for protocols which use a single
     64         * IPC message per exchange only.
     65         *
     66         */
     67        EXCHANGE_ATOMIC = 0,
     68       
     69        /** Exchange management via phone cloning
     70         *
     71         * Suitable for servers which support client
     72         * data tracking by task hashes and do not
     73         * mind cloned phones.
     74         *
     75         */
     76        EXCHANGE_PARALLEL,
     77       
     78        /** Exchange management via mutual exclusion
     79         *
     80         * Suitable for any kind of client/server communication,
     81         * but can limit parallelism.
     82         *
     83         */
     84        EXCHANGE_SERIALIZE
     85} exch_mgmt_t;
     86
     87/** Session data */
     88typedef struct {
     89        /** List of inactive exchanges */
     90        link_t exch_list;
     91       
     92        /** Exchange management style */
     93        exch_mgmt_t mgmt;
     94       
     95        /** Session identification */
     96        int phone;
     97       
     98        /** First clone connection argument */
     99        sysarg_t arg1;
     100       
     101        /** Second clone connection argument */
     102        sysarg_t arg2;
     103       
     104        /** Third clone connection argument */
     105        sysarg_t arg3;
     106       
     107        /** Exchange mutex */
     108        fibril_mutex_t mutex;
     109       
     110        /** Number of opened exchanges */
     111        atomic_t refcnt;
     112} async_sess_t;
     113
     114/** Exchange data */
     115typedef struct {
     116        /** Link into list of inactive exchanges */
     117        link_t sess_link;
     118       
     119        /** Link into global list of inactive exchanges */
     120        link_t global_link;
     121       
     122        /** Session pointer */
     123        async_sess_t *sess;
     124       
     125        /** Exchange identification */
     126        int phone;
     127} async_exch_t;
     128
    57129extern atomic_t threads_in_ipc_wait;
    58130
     
    68140 * User-friendly wrappers for async_send_fast() and async_send_slow(). The
    69141 * macros are in the form async_send_m(), where m denotes the number of payload
    70  * arguments.  Each macros chooses between the fast and the slow version based
     142 * arguments. Each macros chooses between the fast and the slow version based
    71143 * on m.
    72144 */
    73145
    74 #define async_send_0(phoneid, method, dataptr) \
    75         async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
    76 #define async_send_1(phoneid, method, arg1, dataptr) \
    77         async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
    78 #define async_send_2(phoneid, method, arg1, arg2, dataptr) \
    79         async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
    80 #define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \
    81         async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
    82 #define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \
    83         async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    84             (dataptr))
    85 #define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
    86         async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    87             (arg5), (dataptr))
    88 
    89 extern aid_t async_send_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    90     sysarg_t, ipc_call_t *);
    91 extern aid_t async_send_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     146#define async_send_0(exch, method, dataptr) \
     147        async_send_fast(exch, method, 0, 0, 0, 0, dataptr)
     148#define async_send_1(exch, method, arg1, dataptr) \
     149        async_send_fast(exch, method, arg1, 0, 0, 0, dataptr)
     150#define async_send_2(exch, method, arg1, arg2, dataptr) \
     151        async_send_fast(exch, method, arg1, arg2, 0, 0, dataptr)
     152#define async_send_3(exch, method, arg1, arg2, arg3, dataptr) \
     153        async_send_fast(exch, method, arg1, arg2, arg3, 0, dataptr)
     154#define async_send_4(exch, method, arg1, arg2, arg3, arg4, dataptr) \
     155        async_send_fast(exch, method, arg1, arg2, arg3, arg4, dataptr)
     156#define async_send_5(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
     157        async_send_slow(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr)
     158
     159extern aid_t async_send_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
    92160    sysarg_t, sysarg_t, ipc_call_t *);
     161extern aid_t async_send_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     162    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
     163
    93164extern void async_wait_for(aid_t, sysarg_t *);
    94165extern int async_wait_timeout(aid_t, sysarg_t *, suseconds_t);
    95166
    96167extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
    97     ipc_call_t *, void (*)(ipc_callid_t, ipc_call_t *));
     168    ipc_call_t *, async_client_conn_t);
     169
    98170extern void async_usleep(suseconds_t);
    99171extern void async_create_manager(void);
     
    102174extern void async_set_client_data_constructor(async_client_data_ctor_t);
    103175extern void async_set_client_data_destructor(async_client_data_dtor_t);
    104 
    105 extern void *async_client_data_get(void);
     176extern void *async_get_client_data(void);
    106177
    107178extern void async_set_client_connection(async_client_conn_t);
     
    112183 */
    113184
    114 extern void async_msg_0(int, sysarg_t);
    115 extern void async_msg_1(int, sysarg_t, sysarg_t);
    116 extern void async_msg_2(int, sysarg_t, sysarg_t, sysarg_t);
    117 extern void async_msg_3(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
    118 extern void async_msg_4(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
    119 extern void async_msg_5(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     185extern void async_msg_0(async_exch_t *, sysarg_t);
     186extern void async_msg_1(async_exch_t *, sysarg_t, sysarg_t);
     187extern void async_msg_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t);
     188extern void async_msg_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
     189extern void async_msg_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    120190    sysarg_t);
     191extern void async_msg_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     192    sysarg_t, sysarg_t);
    121193
    122194/*
     
    138210 */
    139211
    140 extern int async_forward_fast(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
    141     unsigned int);
    142 extern int async_forward_slow(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
    143     sysarg_t, sysarg_t, sysarg_t, unsigned int);
     212extern int async_forward_fast(ipc_callid_t, async_exch_t *, sysarg_t, sysarg_t,
     213    sysarg_t, unsigned int);
     214extern int async_forward_slow(ipc_callid_t, async_exch_t *, sysarg_t, sysarg_t,
     215    sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
    144216
    145217/*
     
    150222 */
    151223
    152 #define async_req_0_0(phoneid, method) \
    153         async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
    154             NULL)
    155 #define async_req_0_1(phoneid, method, r1) \
    156         async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
    157             NULL)
    158 #define async_req_0_2(phoneid, method, r1, r2) \
    159         async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
    160             NULL)
    161 #define async_req_0_3(phoneid, method, r1, r2, r3) \
    162         async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
    163             NULL)
    164 #define async_req_0_4(phoneid, method, r1, r2, r3, r4) \
    165         async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
    166             NULL)
    167 #define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \
    168         async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
    169             (r5))
    170 #define async_req_1_0(phoneid, method, arg1) \
    171         async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
    172             NULL, NULL)
    173 #define async_req_1_1(phoneid, method, arg1, rc1) \
    174         async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
    175             NULL, NULL)
    176 #define async_req_1_2(phoneid, method, arg1, rc1, rc2) \
    177         async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
    178             NULL, NULL)
    179 #define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \
    180         async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
    181             NULL, NULL)
    182 #define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \
    183         async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
    184             (rc4), NULL)
    185 #define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \
    186         async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
    187             (rc4), (rc5))
    188 #define async_req_2_0(phoneid, method, arg1, arg2) \
    189         async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
     224#define async_req_0_0(exch, method) \
     225        async_req_fast(exch, method, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)
     226#define async_req_0_1(exch, method, r1) \
     227        async_req_fast(exch, method, 0, 0, 0, 0, r1, NULL, NULL, NULL, NULL)
     228#define async_req_0_2(exch, method, r1, r2) \
     229        async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, NULL, NULL, NULL)
     230#define async_req_0_3(exch, method, r1, r2, r3) \
     231        async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, NULL, NULL)
     232#define async_req_0_4(exch, method, r1, r2, r3, r4) \
     233        async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, NULL)
     234#define async_req_0_5(exch, method, r1, r2, r3, r4, r5) \
     235        async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, r5)
     236
     237#define async_req_1_0(exch, method, arg1) \
     238        async_req_fast(exch, method, arg1, 0, 0, 0, NULL, NULL, NULL, NULL, \
     239            NULL)
     240#define async_req_1_1(exch, method, arg1, rc1) \
     241        async_req_fast(exch, method, arg1, 0, 0, 0, rc1, NULL, NULL, NULL, \
     242            NULL)
     243#define async_req_1_2(exch, method, arg1, rc1, rc2) \
     244        async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, NULL, NULL, \
     245            NULL)
     246#define async_req_1_3(exch, method, arg1, rc1, rc2, rc3) \
     247        async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, NULL, \
     248            NULL)
     249#define async_req_1_4(exch, method, arg1, rc1, rc2, rc3, rc4) \
     250        async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
     251            NULL)
     252#define async_req_1_5(exch, method, arg1, rc1, rc2, rc3, rc4, rc5) \
     253        async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
     254            rc5)
     255
     256#define async_req_2_0(exch, method, arg1, arg2) \
     257        async_req_fast(exch, method, arg1, arg2, 0, 0, NULL, NULL, NULL, \
     258            NULL, NULL)
     259#define async_req_2_1(exch, method, arg1, arg2, rc1) \
     260        async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, NULL, NULL, \
     261            NULL, NULL)
     262#define async_req_2_2(exch, method, arg1, arg2, rc1, rc2) \
     263        async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, NULL, NULL, \
     264            NULL)
     265#define async_req_2_3(exch, method, arg1, arg2, rc1, rc2, rc3) \
     266        async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, NULL, \
     267            NULL)
     268#define async_req_2_4(exch, method, arg1, arg2, rc1, rc2, rc3, rc4) \
     269        async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
     270            NULL)
     271#define async_req_2_5(exch, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
     272        async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
     273            rc5)
     274
     275#define async_req_3_0(exch, method, arg1, arg2, arg3) \
     276        async_req_fast(exch, method, arg1, arg2, arg3, 0, NULL, NULL, NULL, \
     277            NULL, NULL)
     278#define async_req_3_1(exch, method, arg1, arg2, arg3, rc1) \
     279        async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, NULL, NULL, \
     280            NULL, NULL)
     281#define async_req_3_2(exch, method, arg1, arg2, arg3, rc1, rc2) \
     282        async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, NULL, \
     283            NULL, NULL)
     284#define async_req_3_3(exch, method, arg1, arg2, arg3, rc1, rc2, rc3) \
     285        async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
     286            NULL, NULL)
     287#define async_req_3_4(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
     288        async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
     289            rc4, NULL)
     290#define async_req_3_5(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
     291    rc5) \
     292        async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
     293            rc4, rc5)
     294
     295#define async_req_4_0(exch, method, arg1, arg2, arg3, arg4) \
     296        async_req_fast(exch, method, arg1, arg2, arg3, arg4, NULL, NULL, \
    190297            NULL, NULL, NULL)
    191 #define async_req_2_1(phoneid, method, arg1, arg2, rc1) \
    192         async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
     298#define async_req_4_1(exch, method, arg1, arg2, arg3, arg4, rc1) \
     299        async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, NULL, \
    193300            NULL, NULL, NULL)
    194 #define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \
    195         async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
     301#define async_req_4_2(exch, method, arg1, arg2, arg3, arg4, rc1, rc2) \
     302        async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, NULL, \
     303            NULL, NULL)
     304#define async_req_4_3(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
     305        async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
     306            NULL, NULL)
     307#define async_req_4_4(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
     308    rc4) \
     309        async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
     310            rc4, NULL)
     311#define async_req_4_5(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
     312    rc4, rc5) \
     313        async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
     314            rc4, rc5)
     315
     316#define async_req_5_0(exch, method, arg1, arg2, arg3, arg4, arg5) \
     317        async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, NULL, \
     318            NULL, NULL, NULL, NULL)
     319#define async_req_5_1(exch, method, arg1, arg2, arg3, arg4, arg5, rc1) \
     320        async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, \
     321            NULL, NULL, NULL, NULL)
     322#define async_req_5_2(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
     323        async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
    196324            NULL, NULL, NULL)
    197 #define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \
    198         async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
    199             (rc3), NULL, NULL)
    200 #define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \
    201         async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
    202             (rc3), (rc4), NULL)
    203 #define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
    204         async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
    205             (rc3), (rc4), (rc5))
    206 #define async_req_3_0(phoneid, method, arg1, arg2, arg3) \
    207         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
    208             NULL, NULL, NULL)
    209 #define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \
    210         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    211             NULL, NULL, NULL, NULL)
    212 #define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \
    213         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    214             (rc2), NULL, NULL, NULL)
    215 #define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \
    216         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    217             (rc2), (rc3), NULL, NULL)
    218 #define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
    219         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    220             (rc2), (rc3), (rc4), NULL)
    221 #define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
    222     rc5) \
    223         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
    224             (rc2), (rc3), (rc4), (rc5))
    225 #define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
    226         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
    227             NULL, NULL, NULL, NULL)
    228 #define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \
    229         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
    230             NULL, NULL, NULL, NULL)
    231 #define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \
    232         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
    233             (rc2), NULL, NULL, NULL)
    234 #define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
    235         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
    236             (rc2), (rc3), NULL, NULL)
    237 #define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
    238     rc4) \
    239         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    240             (rc1), (rc2), (rc3), (rc4), NULL)
    241 #define async_req_4_5(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
    242     rc4, rc5) \
    243         async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    244             (rc1), (rc2), (rc3), (rc4), (rc5))
    245 #define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
    246         async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    247             (arg5), NULL, NULL, NULL, NULL, NULL)
    248 #define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \
    249         async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    250             (arg5), (rc1), NULL, NULL, NULL, NULL)
    251 #define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
    252         async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    253             (arg5), (rc1), (rc2), NULL, NULL, NULL)
    254 #define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     325#define async_req_5_3(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
    255326    rc3) \
    256         async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    257             (arg5), (rc1), (rc2), (rc3), NULL, NULL)
    258 #define async_req_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     327        async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     328            rc3, NULL, NULL)
     329#define async_req_5_4(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
    259330    rc3, rc4) \
    260         async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    261             (arg5), (rc1), (rc2), (rc3), (rc4), NULL)
    262 #define async_req_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     331        async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     332            rc3, rc4, NULL)
     333#define async_req_5_5(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
    263334    rc3, rc4, rc5) \
    264         async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
    265             (arg5), (rc1), (rc2), (rc3), (rc4), (rc5))
    266 
    267 extern sysarg_t async_req_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    268     sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
    269 extern sysarg_t async_req_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     335        async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     336            rc3, rc4, rc5)
     337
     338extern sysarg_t async_req_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
    270339    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
    271340    sysarg_t *);
    272 
    273 static inline void async_serialize_start(void)
    274 {
    275         fibril_inc_sercount();
    276 }
    277 
    278 static inline void async_serialize_end(void)
    279 {
    280         fibril_dec_sercount();
    281 }
    282 
    283 extern int async_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t,
     341extern sysarg_t async_req_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     342    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
     343    sysarg_t *, sysarg_t *);
     344
     345extern async_sess_t *async_connect_me(exch_mgmt_t, async_exch_t *);
     346extern async_sess_t *async_connect_me_to(exch_mgmt_t, async_exch_t *, sysarg_t,
     347    sysarg_t, sysarg_t);
     348extern async_sess_t *async_connect_me_to_blocking(exch_mgmt_t, async_exch_t *,
     349    sysarg_t, sysarg_t, sysarg_t);
     350extern async_sess_t *async_connect_kbox(task_id_t);
     351
     352extern int async_connect_to_me(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
    284353    async_client_conn_t);
    285 extern int async_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
    286 extern int async_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
    287 extern int async_connect_kbox(task_id_t);
    288 extern int async_hangup(int);
     354
     355extern int async_hangup(async_sess_t *);
    289356extern void async_poke(void);
    290357
     358extern async_exch_t *async_exchange_begin(async_sess_t *);
     359extern void async_exchange_end(async_exch_t *);
     360
    291361/*
    292362 * User-friendly wrappers for async_share_in_start().
    293363 */
    294364
    295 #define async_share_in_start_0_0(phoneid, dst, size) \
    296         async_share_in_start((phoneid), (dst), (size), 0, NULL)
    297 #define async_share_in_start_0_1(phoneid, dst, size, flags) \
    298         async_share_in_start((phoneid), (dst), (size), 0, (flags))
    299 #define async_share_in_start_1_0(phoneid, dst, size, arg) \
    300         async_share_in_start((phoneid), (dst), (size), (arg), NULL)
    301 #define async_share_in_start_1_1(phoneid, dst, size, arg, flags) \
    302         async_share_in_start((phoneid), (dst), (size), (arg), (flags))
    303 
    304 extern int async_share_in_start(int, void *, size_t, sysarg_t, unsigned int *);
     365#define async_share_in_start_0_0(exch, dst, size) \
     366        async_share_in_start(exch, dst, size, 0, NULL)
     367#define async_share_in_start_0_1(exch, dst, size, flags) \
     368        async_share_in_start(exch, dst, size, 0, flags)
     369#define async_share_in_start_1_0(exch, dst, size, arg) \
     370        async_share_in_start(exch, dst, size, arg, NULL)
     371#define async_share_in_start_1_1(exch, dst, size, arg, flags) \
     372        async_share_in_start(exch, dst, size, arg, flags)
     373
     374extern int async_share_in_start(async_exch_t *, void *, size_t, sysarg_t,
     375    unsigned int *);
    305376extern bool async_share_in_receive(ipc_callid_t *, size_t *);
    306377extern int async_share_in_finalize(ipc_callid_t, void *, unsigned int);
    307378
    308 extern int async_share_out_start(int, void *, unsigned int);
     379extern int async_share_out_start(async_exch_t *, void *, unsigned int);
    309380extern bool async_share_out_receive(ipc_callid_t *, size_t *, unsigned int *);
    310381extern int async_share_out_finalize(ipc_callid_t, void *);
     
    314385 */
    315386
    316 #define async_data_read_forward_0_0(phoneid, method, answer) \
    317         async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
    318 #define async_data_read_forward_0_1(phoneid, method, answer) \
    319         async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
    320 #define async_data_read_forward_1_0(phoneid, method, arg1, answer) \
    321         async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
    322 #define async_data_read_forward_1_1(phoneid, method, arg1, answer) \
    323         async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer))
    324 #define async_data_read_forward_2_0(phoneid, method, arg1, arg2, answer) \
    325         async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL)
    326 #define async_data_read_forward_2_1(phoneid, method, arg1, arg2, answer) \
    327         async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
    328             (answer))
    329 #define async_data_read_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
    330         async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
    331             NULL)
    332 #define async_data_read_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
    333         async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
    334             (answer))
    335 #define async_data_read_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
    336         async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    337             (arg4), NULL)
    338 #define async_data_read_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
    339         async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    340             (arg4), (answer))
    341 
    342 extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);
    343 #define async_data_read_start(p, buf, len) \
    344         async_data_read_start_generic((p), (buf), (len), IPC_XF_NONE)
    345 
    346 extern int async_data_read_start_generic(int, void *, size_t, int);
     387#define async_data_read_forward_0_0(exch, method, answer) \
     388        async_data_read_forward_fast(exch, method, 0, 0, 0, 0, NULL)
     389#define async_data_read_forward_0_1(exch, method, answer) \
     390        async_data_read_forward_fast(exch, method, 0, 0, 0, 0, answer)
     391#define async_data_read_forward_1_0(exch, method, arg1, answer) \
     392        async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
     393#define async_data_read_forward_1_1(exch, method, arg1, answer) \
     394        async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, answer)
     395#define async_data_read_forward_2_0(exch, method, arg1, arg2, answer) \
     396        async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
     397#define async_data_read_forward_2_1(exch, method, arg1, arg2, answer) \
     398        async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
     399#define async_data_read_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
     400        async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, NULL)
     401#define async_data_read_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
     402        async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, \
     403            answer)
     404#define async_data_read_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
     405    answer) \
     406        async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
     407            NULL)
     408#define async_data_read_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
     409    answer) \
     410        async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
     411            answer)
     412
     413extern aid_t async_data_read(async_exch_t *, void *, size_t, ipc_call_t *);
     414extern int async_data_read_start(async_exch_t *, void *, size_t);
    347415extern bool async_data_read_receive(ipc_callid_t *, size_t *);
    348416extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
    349417
    350 extern int async_data_read_forward_fast(int, sysarg_t, sysarg_t, sysarg_t,
    351     sysarg_t, sysarg_t, ipc_call_t *);
     418extern int async_data_read_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
     419    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
    352420
    353421/*
     
    355423 */
    356424
    357 #define async_data_write_forward_0_0(phoneid, method, answer) \
    358         async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
    359 #define async_data_write_forward_0_1(phoneid, method, answer) \
    360         async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
    361 #define async_data_write_forward_1_0(phoneid, method, arg1, answer) \
    362         async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
    363 #define async_data_write_forward_1_1(phoneid, method, arg1, answer) \
    364         async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, \
    365             (answer))
    366 #define async_data_write_forward_2_0(phoneid, method, arg1, arg2, answer) \
    367         async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
    368             NULL)
    369 #define async_data_write_forward_2_1(phoneid, method, arg1, arg2, answer) \
    370         async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
    371             (answer))
    372 #define async_data_write_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
    373         async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    374             0, NULL)
    375 #define async_data_write_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
    376         async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    377             0, (answer))
    378 #define async_data_write_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
    379         async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    380             (arg4), NULL)
    381 #define async_data_write_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
    382         async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
    383             (arg4), (answer))
    384 
    385 #define async_data_write_start(p, buf, len) \
    386         async_data_write_start_generic((p), (buf), (len), IPC_XF_NONE)
    387 
    388 extern int async_data_write_start_generic(int, const void *, size_t, int);
     425#define async_data_write_forward_0_0(exch, method, answer) \
     426        async_data_write_forward_fast(exch, method, 0, 0, 0, 0, NULL)
     427#define async_data_write_forward_0_1(exch, method, answer) \
     428        async_data_write_forward_fast(exch, method, 0, 0, 0, 0, answer)
     429#define async_data_write_forward_1_0(exch, method, arg1, answer) \
     430        async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
     431#define async_data_write_forward_1_1(exch, method, arg1, answer) \
     432        async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, answer)
     433#define async_data_write_forward_2_0(exch, method, arg1, arg2, answer) \
     434        async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
     435#define async_data_write_forward_2_1(exch, method, arg1, arg2, answer) \
     436        async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
     437#define async_data_write_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
     438        async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
     439            NULL)
     440#define async_data_write_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
     441        async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
     442            answer)
     443#define async_data_write_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
     444    answer) \
     445        async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
     446            NULL)
     447#define async_data_write_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
     448    answer) \
     449        async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
     450            answer)
     451
     452extern int async_data_write_start(async_exch_t *, const void *, size_t);
    389453extern bool async_data_write_receive(ipc_callid_t *, size_t *);
    390454extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
     
    394458extern void async_data_write_void(sysarg_t);
    395459
    396 extern int async_data_write_forward_fast(int, sysarg_t, sysarg_t, sysarg_t,
    397     sysarg_t, sysarg_t, ipc_call_t *);
     460extern int async_data_write_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
     461    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
     462
     463extern int async_exchange_clone(async_exch_t *, async_exch_t *);
     464extern async_sess_t *async_clone_receive(exch_mgmt_t);
     465extern async_sess_t *async_callback_receive(exch_mgmt_t);
    398466
    399467#endif
  • uspace/lib/c/include/device/char_dev.h

    r764d71e r79ae36dd  
    3636#define LIBC_DEVICE_CHAR_DEV_H_
    3737
     38#include <async.h>
     39
    3840typedef enum {
    3941        CHAR_DEV_READ = 0,
     
    4143} char_dev_method_t;
    4244
    43 ssize_t char_dev_read(int dev_phone, void *buf, size_t len);
    44 ssize_t char_dev_write(int dev_phone, void *buf, size_t len);
     45extern ssize_t char_dev_read(async_sess_t *, void *, size_t);
     46extern ssize_t char_dev_write(async_sess_t *, void *, size_t);
    4547
    4648#endif
  • uspace/lib/c/include/device/hw_res.h

    r764d71e r79ae36dd  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28  
     28
    2929/** @addtogroup libc
    3030 * @{
     
    3232/** @file
    3333 */
    34  
     34
    3535#ifndef LIBC_DEVICE_HW_RES_H_
    3636#define LIBC_DEVICE_HW_RES_H_
    3737
    3838#include <ipc/dev_iface.h>
     39#include <async.h>
    3940#include <bool.h>
    4041
     
    4849typedef enum {
    4950        INTERRUPT,
    50         IO_RANGE, 
     51        IO_RANGE,
    5152        MEM_RANGE
    5253} hw_res_type_t;
     
    6667                        size_t size;
    6768                } mem_range;
    68 
     69               
    6970                struct {
    7071                        uint64_t address;
     
    7273                        size_t size;
    7374                } io_range;
    74 
     75               
    7576                struct {
    7677                        int irq;
     
    8889        if (hw_res->resources != NULL) {
    8990                free(hw_res->resources);
    90 
    9191                hw_res->resources = NULL;
    9292        }
    93 
     93       
    9494        hw_res->count = 0;
    9595}
    9696
    97 extern int hw_res_get_resource_list(int, hw_resource_list_t *);
    98 extern bool hw_res_enable_interrupt(int);
     97extern int hw_res_get_resource_list(async_sess_t *, hw_resource_list_t *);
     98extern bool hw_res_enable_interrupt(async_sess_t *);
    9999
    100100#endif
  • uspace/lib/c/include/devman.h

    r764d71e r79ae36dd  
    4141#include <bool.h>
    4242
    43 extern int devman_get_phone(devman_interface_t, unsigned int);
    44 extern void devman_hangup_phone(devman_interface_t);
     43extern async_exch_t *devman_exchange_begin_blocking(devman_interface_t);
     44extern async_exch_t *devman_exchange_begin(devman_interface_t);
     45extern void devman_exchange_end(async_exch_t *);
    4546
    4647extern int devman_driver_register(const char *, async_client_conn_t);
     
    4849    devman_handle_t, devman_handle_t *);
    4950
    50 extern int devman_device_connect(devman_handle_t, unsigned int);
    51 extern int devman_parent_device_connect(devman_handle_t, unsigned int);
     51extern async_sess_t *devman_device_connect(exch_mgmt_t, devman_handle_t,
     52    unsigned int);
     53extern async_sess_t *devman_parent_device_connect(exch_mgmt_t, devman_handle_t,
     54    unsigned int);
    5255
    5356extern int devman_device_get_handle(const char *, devman_handle_t *,
  • uspace/lib/c/include/devman_obsolete.h

    r764d71e r79ae36dd  
    11/*
    2  * Copyright (c) 2010 Jakub Jermar
     2 * Copyright (c) 2009 Jiri Svoboda
     3 * Copyright (c) 2010 Lenka Trochtova
    34 * All rights reserved.
    45 *
     
    3334 */
    3435
    35 #ifndef LIBC_ASYNC_SESS_H_
    36 #define LIBC_ASYNC_SESS_H_
     36#ifndef LIBC_DEVMAN_OBSOLETE_H_
     37#define LIBC_DEVMAN_OBSOLETE_H_
    3738
    38 #include <adt/list.h>
     39#include <ipc/devman.h>
     40#include <async.h>
     41#include <bool.h>
    3942
    40 typedef struct {
    41         int sess_phone;         /**< Phone for cloning off the connections. */
    42         sysarg_t connect_arg1;  /**< Argument for CONNECT_ME_TO. */
    43         link_t conn_head;       /**< List of open data connections. */
    44         link_t sess_link;       /**< Link in global list of open sessions. */
    45 } async_sess_t;
     43extern int devman_obsolete_get_phone(devman_interface_t, unsigned int);
     44extern void devman_obsolete_hangup_phone(devman_interface_t);
    4645
    47 extern void async_session_create(async_sess_t *, int, sysarg_t);
    48 extern void async_session_destroy(async_sess_t *);
    49 extern int async_exchange_begin(async_sess_t *);
    50 extern void async_exchange_end(async_sess_t *, int);
     46extern int devman_obsolete_device_connect(devman_handle_t, unsigned int);
     47extern int devman_obsolete_parent_device_connect(devman_handle_t, unsigned int);
    5148
    5249#endif
  • uspace/lib/c/include/devmap.h

    r764d71e r79ae36dd  
    4040#include <bool.h>
    4141
    42 extern int devmap_get_phone(devmap_interface_t, unsigned int);
    43 extern void devmap_hangup_phone(devmap_interface_t iface);
     42extern async_exch_t *devmap_exchange_begin_blocking(devmap_interface_t);
     43extern async_exch_t *devmap_exchange_begin(devmap_interface_t);
     44extern void devmap_exchange_end(async_exch_t *);
    4445
    4546extern int devmap_driver_register(const char *, async_client_conn_t);
    4647extern int devmap_device_register(const char *, devmap_handle_t *);
    47 extern int devmap_device_register_with_iface(const char *, devmap_handle_t *, sysarg_t);
     48extern int devmap_device_register_with_iface(const char *, devmap_handle_t *,
     49    sysarg_t);
    4850
    49 extern int devmap_device_get_handle(const char *, devmap_handle_t *, unsigned int);
    50 extern int devmap_namespace_get_handle(const char *, devmap_handle_t *, unsigned int);
     51extern int devmap_device_get_handle(const char *, devmap_handle_t *,
     52    unsigned int);
     53extern int devmap_namespace_get_handle(const char *, devmap_handle_t *,
     54    unsigned int);
    5155extern devmap_handle_type_t devmap_handle_probe(devmap_handle_t);
    5256
    53 extern int devmap_device_connect(devmap_handle_t, unsigned int);
     57extern async_sess_t *devmap_device_connect(exch_mgmt_t, devmap_handle_t,
     58    unsigned int);
    5459
    5560extern int devmap_null_create(void);
  • uspace/lib/c/include/io/console.h

    r764d71e r79ae36dd  
    3636#define LIBC_IO_CONSOLE_H_
    3737
     38#include <sys/time.h>
     39#include <async.h>
    3840#include <bool.h>
    39 
    40 typedef enum {
    41         KEY_PRESS,
    42         KEY_RELEASE
    43 } console_ev_type_t;
     41#include <stdio.h>
    4442
    4543typedef enum {
     
    5048} console_caps_t;
    5149
     50/** Console control structure. */
     51typedef struct {
     52        /** Console input file */
     53        FILE *input;
     54       
     55        /** Console output file */
     56        FILE *output;
     57       
     58        /** Console input session */
     59        async_sess_t *input_sess;
     60       
     61        /** Console output session */
     62        async_sess_t *output_sess;
     63       
     64        /** Input request call with timeout */
     65        ipc_call_t input_call;
     66       
     67        /** Input response with timeout */
     68        aid_t input_aid;
     69} console_ctrl_t;
     70
     71typedef enum {
     72        KEY_PRESS,
     73        KEY_RELEASE
     74} kbd_event_type_t;
     75
    5276/** Console event structure. */
    5377typedef struct {
    5478        /** Press or release event. */
    55         console_ev_type_t type;
     79        kbd_event_type_t type;
    5680       
    5781        /** Keycode of the key that was pressed or released. */
     
    6387        /** The character that was generated or '\0' for none. */
    6488        wchar_t c;
    65 } console_event_t;
     89} kbd_event_t;
    6690
    67 extern void console_clear(int phone);
     91extern console_ctrl_t *console_init(FILE *, FILE *);
     92extern void console_done(console_ctrl_t *);
     93extern bool console_kcon(void);
    6894
    69 extern int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows);
    70 extern int console_get_pos(int phone, sysarg_t *col, sysarg_t *row);
    71 extern void console_set_pos(int phone, sysarg_t col, sysarg_t row);
     95extern void console_flush(console_ctrl_t *);
     96extern void console_clear(console_ctrl_t *);
    7297
    73 extern void console_set_style(int phone, uint8_t style);
    74 extern void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
    75     uint8_t flags);
    76 extern void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color);
     98extern int console_get_size(console_ctrl_t *, sysarg_t *, sysarg_t *);
     99extern int console_get_pos(console_ctrl_t *, sysarg_t *, sysarg_t *);
     100extern void console_set_pos(console_ctrl_t *, sysarg_t, sysarg_t);
    77101
    78 extern void console_cursor_visibility(int phone, bool show);
    79 extern int console_get_color_cap(int phone, sysarg_t *ccap);
    80 extern void console_kcon_enable(int phone);
     102extern void console_set_style(console_ctrl_t *, uint8_t);
     103extern void console_set_color(console_ctrl_t *, uint8_t, uint8_t, uint8_t);
     104extern void console_set_rgb_color(console_ctrl_t *, uint32_t, uint32_t);
    81105
    82 extern bool console_get_event(int phone, console_event_t *event);
     106extern void console_cursor_visibility(console_ctrl_t *, bool);
     107extern int console_get_color_cap(console_ctrl_t *, sysarg_t *);
     108extern bool console_get_kbd_event(console_ctrl_t *, kbd_event_t *);
     109extern bool console_get_kbd_event_timeout(console_ctrl_t *, kbd_event_t *,
     110    suseconds_t *);
    83111
    84112#endif
  • uspace/lib/c/include/ipc/devmap.h

    r764d71e r79ae36dd  
    3131 */
    3232
    33 #ifndef DEVMAP_DEVMAP_H_
    34 #define DEVMAP_DEVMAP_H_
     33#ifndef LIBC_IPC_DEVMAP_H_
     34#define LIBC_IPC_DEVMAP_H_
    3535
    3636#include <ipc/common.h>
  • uspace/lib/c/include/ipc/ipc.h

    r764d71e r79ae36dd  
    4242#include <sys/types.h>
    4343#include <ipc/common.h>
     44#include <kernel/ipc/ipc_methods.h>
    4445#include <kernel/synch/synch.h>
    4546#include <task.h>
     
    255256extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t *,
    256257    sysarg_t *);
     258extern int ipc_connect_me(int);
    257259extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
    258260extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
  • uspace/lib/c/include/ipc/ns.h

    r764d71e r79ae36dd  
    3333 */
    3434
    35 #ifndef LIBC_NS_H_
    36 #define LIBC_NS_H_
     35#ifndef LIBC_IPC_NS_H_
     36#define LIBC_IPC_NS_H_
    3737
    38 #include <sys/types.h>
    3938#include <ipc/common.h>
    4039
     
    4645} ns_request_t;
    4746
    48 extern int service_register(sysarg_t);
    49 extern int service_connect(sysarg_t, sysarg_t, sysarg_t);
    50 extern int service_connect_blocking(sysarg_t, sysarg_t, sysarg_t);
    51 
    5247#endif
    5348
  • uspace/lib/c/include/ipc/serial_ctl.h

    r764d71e r79ae36dd  
    3232#include <ipc/dev_iface.h>
    3333
    34 /** ipc methods for getting/setting serial communication properties
    35  *      1st ipc arg: baud rate
    36  *      2nd ipc arg: parity
    37  *      3rd ipc arg: number of bits in one word
    38  *      4th ipc arg: number of stop bits
     34/** IPC methods for getting/setting serial communication properties
     35 *
     36 * 1st IPC arg: baud rate
     37 * 2nd IPC arg: parity
     38 * 3rd IPC arg: number of bits in one word
     39 * 4th IPC arg: number of stop bits
     40 *
    3941 */
    40 typedef enum { 
     42typedef enum {
    4143        SERIAL_GET_COM_PROPS = DEV_FIRST_CUSTOM_METHOD,
    4244        SERIAL_SET_COM_PROPS
     
    4850        SERIAL_EVEN_PARITY = 3,
    4951        SERIAL_MARK_PARITY = 5,
    50         SERIAL_SPACE_PARITY = 7 
     52        SERIAL_SPACE_PARITY = 7
    5153} serial_parity_t;
    5254
  • uspace/lib/c/include/ipc/vfs.h

    r764d71e r79ae36dd  
    6969        VFS_IN_FSTAT,
    7070        VFS_IN_CLOSE,
     71        VFS_IN_PING,
    7172        VFS_IN_MOUNT,
    7273        VFS_IN_UNMOUNT,
  • uspace/lib/c/include/loader/loader.h

    r764d71e r79ae36dd  
    4040#include <vfs/vfs.h>
    4141
    42 /** Abstraction of a loader connection */
    43 typedef struct {
    44         /** ID of the phone connected to the loader. */
    45         int phone_id;
    46 } loader_t;
     42/** Forward declararion */
     43struct loader;
     44typedef struct loader loader_t;
    4745
    4846extern int loader_spawn(const char *);
  • uspace/lib/c/include/stdio.h

    r764d71e r79ae36dd  
    9797};
    9898
    99 typedef struct {
    100         /** Linked list pointer. */
    101         link_t link;
    102        
    103         /** Underlying file descriptor. */
    104         int fd;
    105        
    106         /** Error indicator. */
    107         int error;
    108        
    109         /** End-of-file indicator. */
    110         int eof;
    111        
    112         /** Klog indicator */
    113         int klog;
    114        
    115         /** Phone to the file provider */
    116         int phone;
    117 
    118         /**
    119          * Non-zero if the stream needs sync on fflush(). XXX change
    120          * console semantics so that sync is not needed.
    121          */
    122         int need_sync;
    123 
    124         /** Buffering type */
    125         enum _buffer_type btype;
    126 
    127         /** Buffer */
    128         uint8_t *buf;
    129 
    130         /** Buffer size */
    131         size_t buf_size;
    132 
    133         /** Buffer state */
    134         enum _buffer_state buf_state;
    135 
    136         /** Buffer I/O pointer */
    137         uint8_t *buf_head;
    138 
    139         /** Points to end of occupied space when in read mode. */
    140         uint8_t *buf_tail;
    141 } FILE;
     99/** Forward declaration */
     100struct _IO_FILE;
     101typedef struct _IO_FILE FILE;
    142102
    143103extern FILE *stdin;
  • uspace/lib/c/include/udebug.h

    r764d71e r79ae36dd  
    3838#include <kernel/udebug/udebug.h>
    3939#include <sys/types.h>
     40#include <async.h>
    4041
    4142typedef sysarg_t thash_t;
    4243
    43 int udebug_begin(int);
    44 int udebug_end(int);
    45 int udebug_set_evmask(int, udebug_evmask_t);
    46 int udebug_thread_read(int, void *, size_t , size_t *, size_t *);
    47 int udebug_name_read(int, void *, size_t, size_t *, size_t *);
    48 int udebug_areas_read(int, void *, size_t, size_t *, size_t *);
    49 int udebug_mem_read(int, void *, uintptr_t, size_t);
    50 int udebug_args_read(int, thash_t, sysarg_t *);
    51 int udebug_regs_read(int, thash_t, void *);
    52 int udebug_go(int, thash_t, udebug_event_t *, sysarg_t *, sysarg_t *);
    53 int udebug_stop(int, thash_t);
     44extern int udebug_begin(async_sess_t *);
     45extern int udebug_end(async_sess_t *);
     46extern int udebug_set_evmask(async_sess_t *, udebug_evmask_t);
     47extern int udebug_thread_read(async_sess_t *, void *, size_t , size_t *,
     48    size_t *);
     49extern int udebug_name_read(async_sess_t *, void *, size_t, size_t *,
     50    size_t *);
     51extern int udebug_areas_read(async_sess_t *, void *, size_t, size_t *,
     52    size_t *);
     53extern int udebug_mem_read(async_sess_t *, void *, uintptr_t, size_t);
     54extern int udebug_args_read(async_sess_t *, thash_t, sysarg_t *);
     55extern int udebug_regs_read(async_sess_t *, thash_t, void *);
     56extern int udebug_go(async_sess_t *, thash_t, udebug_event_t *, sysarg_t *,
     57    sysarg_t *);
     58extern int udebug_stop(async_sess_t *, thash_t);
    5459
    5560#endif
  • uspace/lib/c/include/vfs/vfs.h

    r764d71e r79ae36dd  
    4141#include <stdio.h>
    4242
    43 /**
    44  * This type is a libc version of the VFS triplet.
    45  * It uniquely identifies a file system node within a file system instance.
     43/** Libc version of the VFS triplet.
     44 *
     45 * Unique identification of a file system node
     46 * within a file system instance.
     47 *
    4648 */
    4749typedef struct {
     
    5860
    5961extern int open_node(fdi_node_t *, int);
    60 extern int fd_phone(int);
    6162extern int fd_node(int, fdi_node_t *);
    6263
    6364extern FILE *fopen_node(fdi_node_t *, const char *);
    64 extern int fphone(FILE *);
    6565extern int fnode(FILE *, fdi_node_t *);
    6666
Note: See TracChangeset for help on using the changeset viewer.