Changeset d1e196f7 in mainline for uspace


Ignore:
Timestamp:
2011-08-21T12:04:27Z (14 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8a6ba94
Parents:
1877128 (diff), a6480d5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

Location:
uspace
Files:
2 added
30 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    r1877128 rd1e196f7  
    3737        app/blkdump \
    3838        app/bnchmark \
     39        app/devctl \
    3940        app/edit \
    4041        app/ext2info \
  • uspace/app/lsusb/main.c

    r1877128 rd1e196f7  
    8181                }
    8282                char path[MAX_PATH_LENGTH];
    83                 rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
     83                rc = devman_fun_get_path(dev_handle, path, MAX_PATH_LENGTH);
    8484                if (rc != EOK) {
    8585                        continue;
     
    120120                }
    121121                char path[MAX_PATH_LENGTH];
    122                 rc = devman_get_device_path(hc_handle, path, MAX_PATH_LENGTH);
     122                rc = devman_fun_get_path(hc_handle, path, MAX_PATH_LENGTH);
    123123                if (rc != EOK) {
    124124                        printf(NAME ": Error resolving path of HC with SID %"
  • uspace/app/mkbd/main.c

    r1877128 rd1e196f7  
    240240       
    241241        char path[MAX_PATH_LENGTH];
    242         rc = devman_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
     242        rc = devman_fun_get_path(dev_handle, path, MAX_PATH_LENGTH);
    243243        if (rc != EOK) {
    244244                return ENOMEM;
  • uspace/app/tester/hw/serial/serial1.c

    r1877128 rd1e196f7  
    7272       
    7373        devman_handle_t handle;
    74         int res = devman_device_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
     74        int res = devman_fun_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
    7575            IPC_FLAG_BLOCKING);
    7676        if (res != EOK)
  • uspace/lib/c/arch/ia32/Makefile.common

    r1877128 rd1e196f7  
    2828
    2929CLANG_ARCH = i386
    30 GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer
     30
     31ifeq ($(PROCESSOR),i486)
     32        GCC_CFLAGS += -march=i486 -fno-omit-frame-pointer
     33else
     34        GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer
     35endif
    3136
    3237ENDIANESS = LE
  • uspace/lib/c/arch/ia32/Makefile.inc

    r1877128 rd1e196f7  
    2828
    2929ARCH_SOURCES = \
    30         arch/$(UARCH)/src/entry.s \
     30        arch/$(UARCH)/src/entry.S \
    3131        arch/$(UARCH)/src/entryjmp.s \
    3232        arch/$(UARCH)/src/thread_entry.s \
  • uspace/lib/c/arch/ia32/include/ddi.h

    r1877128 rd1e196f7  
    4141static inline uint8_t pio_read_8(ioport8_t *port)
    4242{
    43         uint8_t val;
    44        
    45         asm volatile (
    46                 "inb %w[port], %b[val]\n"
    47                 : [val] "=a" (val)
    48                 : [port] "d" (port)
    49         );
    50        
    51         return val;
     43        if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
     44                uint8_t val;
     45               
     46                asm volatile (
     47                        "inb %w[port], %b[val]\n"
     48                        : [val] "=a" (val)
     49                        : [port] "d" (port)
     50                );
     51               
     52                return val;
     53        } else
     54                return (uint8_t) *port;
    5255}
    5356
    5457static inline uint16_t pio_read_16(ioport16_t *port)
    5558{
    56         uint16_t val;
    57        
    58         asm volatile (
    59                 "inw %w[port], %w[val]\n"
    60                 : [val] "=a" (val)
    61                 : [port] "d" (port)
    62         );
    63        
    64         return val;
     59        if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
     60                uint16_t val;
     61               
     62                asm volatile (
     63                        "inw %w[port], %w[val]\n"
     64                        : [val] "=a" (val)
     65                        : [port] "d" (port)
     66                );
     67               
     68                return val;
     69        } else
     70                return (uint16_t) *port;
    6571}
    6672
    6773static inline uint32_t pio_read_32(ioport32_t *port)
    6874{
    69         uint32_t val;
    70        
    71         asm volatile (
    72                 "inl %w[port], %[val]\n"
    73                 : [val] "=a" (val)
    74                 : [port] "d" (port)
    75         );
    76        
    77         return val;
     75        if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
     76                uint32_t val;
     77               
     78                asm volatile (
     79                        "inl %w[port], %[val]\n"
     80                        : [val] "=a" (val)
     81                        : [port] "d" (port)
     82                );
     83               
     84                return val;
     85        } else
     86                return (uint32_t) *port;
    7887}
    7988
    8089static inline void pio_write_8(ioport8_t *port, uint8_t val)
    8190{
    82         asm volatile (
    83                 "outb %b[val], %w[port]\n"
    84                 :: [val] "a" (val), [port] "d" (port)
    85         );
     91        if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
     92                asm volatile (
     93                        "outb %b[val], %w[port]\n"
     94                        :: [val] "a" (val), [port] "d" (port)
     95                );     
     96        } else
     97                *port = val;
    8698}
    8799
    88100static inline void pio_write_16(ioport16_t *port, uint16_t val)
    89101{
    90         asm volatile (
    91                 "outw %w[val], %w[port]\n"
    92                 :: [val] "a" (val), [port] "d" (port)
    93         );
     102        if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
     103                asm volatile (
     104                        "outw %w[val], %w[port]\n"
     105                        :: [val] "a" (val), [port] "d" (port)
     106                );
     107        } else
     108                *port = val;
    94109}
    95110
    96111static inline void pio_write_32(ioport32_t *port, uint32_t val)
    97112{
    98         asm volatile (
    99                 "outl %[val], %w[port]\n"
    100                 :: [val] "a" (val), [port] "d" (port)
    101         );
     113        if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
     114                asm volatile (
     115                        "outl %[val], %w[port]\n"
     116                        :: [val] "a" (val), [port] "d" (port)
     117                );
     118        } else
     119                *port = val;
    102120}
    103121
  • uspace/lib/c/arch/ia32/src/entry.S

    r1877128 rd1e196f7  
    4747        # Do not set %gs, it contains descriptor that can see TLS
    4848       
     49#ifndef PROCESSOR_i486 
    4950        # Detect the mechanism used for making syscalls
    5051        movl $(INTEL_CPUID_STANDARD), %eax
     
    5253        bt $(INTEL_SEP), %edx
    5354        jnc 0f
    54         leal __syscall_fast_func, %eax
    55         movl $__syscall_fast, (%eax)
    56 0:
     55                leal __syscall_fast_func, %eax
     56                movl $__syscall_fast, (%eax)
     57        0:
     58#endif
     59       
    5760        #
    5861        # Create the first stack frame.
  • uspace/lib/c/generic/async.c

    r1877128 rd1e196f7  
    9898#include <ipc/ipc.h>
    9999#include <async.h>
     100#include "private/async.h"
    100101#undef LIBC_ASYNC_C_
    101102
     
    112113#include <mem.h>
    113114#include <stdlib.h>
    114 #include "private/async.h"
     115#include <macros.h>
    115116
    116117#define CLIENT_HASH_TABLE_BUCKETS  32
     
    138139        link_t link;
    139140       
    140         sysarg_t in_task_hash;
     141        task_id_t in_task_id;
    141142        atomic_t refcnt;
    142143        void *data;
     
    150151        link_t link;
    151152       
    152         /** Incoming client task hash. */
    153         sysarg_t in_task_hash;
     153        /** Incoming client task ID. */
     154        task_id_t in_task_id;
    154155       
    155156        /** Incoming phone hash. */
     
    283284{
    284285        assert(key);
     286        assert(keys == 2);
    285287        assert(item);
    286288       
    287289        client_t *client = hash_table_get_instance(item, client_t, link);
    288         return (key[0] == client->in_task_hash);
     290        return (key[0] == LOWER32(client->in_task_id) &&
     291            (key[1] == UPPER32(client->in_task_id)));
    289292}
    290293
     
    574577}
    575578
    576 static client_t *async_client_get(sysarg_t client_hash, bool create)
    577 {
    578         unsigned long key = client_hash;
     579static client_t *async_client_get(task_id_t client_id, bool create)
     580{
     581        unsigned long key[2] = {
     582                LOWER32(client_id),
     583                UPPER32(client_id),
     584        };
    579585        client_t *client = NULL;
    580586
    581587        futex_down(&async_futex);
    582         link_t *lnk = hash_table_find(&client_hash_table, &key);
     588        link_t *lnk = hash_table_find(&client_hash_table, key);
    583589        if (lnk) {
    584590                client = hash_table_get_instance(lnk, client_t, link);
     
    587593                client = malloc(sizeof(client_t));
    588594                if (client) {
    589                         client->in_task_hash = client_hash;
     595                        client->in_task_id = client_id;
    590596                        client->data = async_client_data_create();
    591597               
    592598                        atomic_set(&client->refcnt, 1);
    593                         hash_table_insert(&client_hash_table, &key, &client->link);
     599                        hash_table_insert(&client_hash_table, key, &client->link);
    594600                }
    595601        }
     
    602608{
    603609        bool destroy;
    604         unsigned long key = client->in_task_hash;
     610        unsigned long key[2] = {
     611                LOWER32(client->in_task_id),
     612                UPPER32(client->in_task_id)
     613        };
    605614       
    606615        futex_down(&async_futex);
    607616       
    608617        if (atomic_predec(&client->refcnt) == 0) {
    609                 hash_table_remove(&client_hash_table, &key, 1);
     618                hash_table_remove(&client_hash_table, key, 2);
    610619                destroy = true;
    611620        } else
     
    628637}
    629638
    630 void *async_get_client_data_by_hash(sysarg_t client_hash)
    631 {
    632         client_t *client = async_client_get(client_hash, false);
     639void *async_get_client_data_by_id(task_id_t client_id)
     640{
     641        client_t *client = async_client_get(client_id, false);
    633642        if (!client)
    634643                return NULL;
     
    641650}
    642651
    643 void async_put_client_data_by_hash(sysarg_t client_hash)
    644 {
    645         client_t *client = async_client_get(client_hash, false);
     652void async_put_client_data_by_id(task_id_t client_id)
     653{
     654        client_t *client = async_client_get(client_id, false);
    646655
    647656        assert(client);
     
    680689         */
    681690
    682         client_t *client = async_client_get(fibril_connection->in_task_hash, true);
     691        client_t *client = async_client_get(fibril_connection->in_task_id, true);
    683692        if (!client) {
    684693                ipc_answer_0(fibril_connection->callid, ENOMEM);
     
    737746 * particular fibrils.
    738747 *
    739  * @param in_task_hash  Identification of the incoming connection.
     748 * @param in_task_id    Identification of the incoming connection.
    740749 * @param in_phone_hash Identification of the incoming connection.
    741750 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    751760 *
    752761 */
    753 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     762fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash,
    754763    ipc_callid_t callid, ipc_call_t *call,
    755764    async_client_conn_t cfibril, void *carg)
     
    763772        }
    764773       
    765         conn->in_task_hash = in_task_hash;
     774        conn->in_task_id = in_task_id;
    766775        conn->in_phone_hash = in_phone_hash;
    767776        list_initialize(&conn->msg_queue);
     
    822831        case IPC_M_CONNECT_ME_TO:
    823832                /* Open new connection with fibril, etc. */
    824                 async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
     833                async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
    825834                    callid, call, client_connection, NULL);
    826835                return;
     
    970979{
    971980        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
    972             1, &client_hash_table_ops))
     981            2, &client_hash_table_ops))
    973982                abort();
    974983       
     
    986995        session_ns->arg2 = 0;
    987996        session_ns->arg3 = 0;
     997       
     998        fibril_mutex_initialize(&session_ns->remote_state_mtx);
     999        session_ns->remote_state_data = NULL;
    9881000       
    9891001        list_initialize(&session_ns->exch_list);
     
    14631475                return ENOENT;
    14641476       
    1465         sysarg_t task_hash;
    14661477        sysarg_t phone_hash;
    1467         int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    1468             NULL, NULL, NULL, &task_hash, &phone_hash);
     1478        sysarg_t rc;
     1479
     1480        aid_t req;
     1481        ipc_call_t answer;
     1482        req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1483            &answer);
     1484        async_wait_for(req, &rc);
    14691485        if (rc != EOK)
    1470                 return rc;
    1471        
     1486                return (int) rc;
     1487
     1488        phone_hash = IPC_GET_ARG5(answer);
     1489
    14721490        if (client_receiver != NULL)
    1473                 async_new_connection(task_hash, phone_hash, 0, NULL,
     1491                async_new_connection(answer.in_task_id, phone_hash, 0, NULL,
    14741492                    client_receiver, carg);
    14751493       
     
    15461564        sess->arg3 = 0;
    15471565       
     1566        fibril_mutex_initialize(&sess->remote_state_mtx);
     1567        sess->remote_state_data = NULL;
     1568       
    15481569        list_initialize(&sess->exch_list);
    15491570        fibril_mutex_initialize(&sess->mutex);
     
    16271648        sess->arg3 = arg3;
    16281649       
     1650        fibril_mutex_initialize(&sess->remote_state_mtx);
     1651        sess->remote_state_data = NULL;
     1652       
    16291653        list_initialize(&sess->exch_list);
    16301654        fibril_mutex_initialize(&sess->mutex);
     
    16321656       
    16331657        return sess;
     1658}
     1659
     1660/** Set arguments for new connections.
     1661 *
     1662 * FIXME This is an ugly hack to work around the problem that parallel
     1663 * exchanges are implemented using parallel connections. When we create
     1664 * a callback session, the framework does not know arguments for the new
     1665 * connections.
     1666 *
     1667 * The proper solution seems to be to implement parallel exchanges using
     1668 * tagging.
     1669 */
     1670void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2,
     1671    sysarg_t arg3)
     1672{
     1673        sess->arg1 = arg1;
     1674        sess->arg2 = arg2;
     1675        sess->arg3 = arg3;
    16341676}
    16351677
     
    16771719        sess->arg3 = arg3;
    16781720       
     1721        fibril_mutex_initialize(&sess->remote_state_mtx);
     1722        sess->remote_state_data = NULL;
     1723       
    16791724        list_initialize(&sess->exch_list);
    16801725        fibril_mutex_initialize(&sess->mutex);
     
    17071752        sess->arg2 = 0;
    17081753        sess->arg3 = 0;
     1754       
     1755        fibril_mutex_initialize(&sess->remote_state_mtx);
     1756        sess->remote_state_data = NULL;
    17091757       
    17101758        list_initialize(&sess->exch_list);
     
    23712419        sess->arg3 = 0;
    23722420       
     2421        fibril_mutex_initialize(&sess->remote_state_mtx);
     2422        sess->remote_state_data = NULL;
     2423       
    23732424        list_initialize(&sess->exch_list);
    23742425        fibril_mutex_initialize(&sess->mutex);
     
    24172468        sess->arg3 = 0;
    24182469       
     2470        fibril_mutex_initialize(&sess->remote_state_mtx);
     2471        sess->remote_state_data = NULL;
     2472       
    24192473        list_initialize(&sess->exch_list);
    24202474        fibril_mutex_initialize(&sess->mutex);
     
    24582512        sess->arg2 = 0;
    24592513        sess->arg3 = 0;
     2514       
     2515        fibril_mutex_initialize(&sess->remote_state_mtx);
     2516        sess->remote_state_data = NULL;
    24602517       
    24612518        list_initialize(&sess->exch_list);
     
    24992556}
    25002557
     2558/** Lock and get session remote state
     2559 *
     2560 * Lock and get the local replica of the remote state
     2561 * in stateful sessions. The call should be paired
     2562 * with async_remote_state_release*().
     2563 *
     2564 * @param[in] sess Stateful session.
     2565 *
     2566 * @return Local replica of the remote state.
     2567 *
     2568 */
     2569void *async_remote_state_acquire(async_sess_t *sess)
     2570{
     2571        fibril_mutex_lock(&sess->remote_state_mtx);
     2572        return sess->remote_state_data;
     2573}
     2574
     2575/** Update the session remote state
     2576 *
     2577 * Update the local replica of the remote state
     2578 * in stateful sessions. The remote state must
     2579 * be already locked.
     2580 *
     2581 * @param[in] sess  Stateful session.
     2582 * @param[in] state New local replica of the remote state.
     2583 *
     2584 */
     2585void async_remote_state_update(async_sess_t *sess, void *state)
     2586{
     2587        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2588        sess->remote_state_data = state;
     2589}
     2590
     2591/** Release the session remote state
     2592 *
     2593 * Unlock the local replica of the remote state
     2594 * in stateful sessions.
     2595 *
     2596 * @param[in] sess Stateful session.
     2597 *
     2598 */
     2599void async_remote_state_release(async_sess_t *sess)
     2600{
     2601        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2602       
     2603        fibril_mutex_unlock(&sess->remote_state_mtx);
     2604}
     2605
     2606/** Release the session remote state and end an exchange
     2607 *
     2608 * Unlock the local replica of the remote state
     2609 * in stateful sessions. This is convenience function
     2610 * which gets the session pointer from the exchange
     2611 * and also ends the exchange.
     2612 *
     2613 * @param[in] exch Stateful session's exchange.
     2614 *
     2615 */
     2616void async_remote_state_release_exchange(async_exch_t *exch)
     2617{
     2618        if (exch == NULL)
     2619                return;
     2620       
     2621        async_sess_t *sess = exch->sess;
     2622        assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
     2623       
     2624        async_exchange_end(exch);
     2625        fibril_mutex_unlock(&sess->remote_state_mtx);
     2626}
     2627
    25012628/** @}
    25022629 */
  • uspace/lib/c/generic/async_obsolete.c

    r1877128 rd1e196f7  
    3838#include <async.h>
    3939#include <async_obsolete.h>
     40#include "private/async.h"
    4041#undef LIBC_ASYNC_C_
    4142#undef LIBC_ASYNC_OBSOLETE_C_
     
    4445#include <malloc.h>
    4546#include <errno.h>
    46 #include "private/async.h"
    4747
    4848/** Send message and return id of the sent message.
  • uspace/lib/c/generic/devman.c

    r1877128 rd1e196f7  
    11/*
    22 * Copyright (c) 2007 Josef Cejka
    3  * Copyright (c) 2009 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * Copyright (c) 2010 Lenka Trochtova
    55 * All rights reserved.
     
    8989                        if (devman_driver_block_sess == NULL)
    9090                                devman_driver_block_sess =
    91                                     service_connect_blocking(EXCHANGE_SERIALIZE,
     91                                    service_connect_blocking(EXCHANGE_PARALLEL,
    9292                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    9393                }
     
    138138                if (devman_driver_sess == NULL)
    139139                        devman_driver_sess =
    140                             service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     140                            service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN,
    141141                            DEVMAN_DRIVER, 0);
    142142               
     
    195195       
    196196        exch = devman_exchange_begin(DEVMAN_DRIVER);
    197         async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
     197        async_connect_to_me(exch, 0, 0, 0, conn, NULL);
    198198        devman_exchange_end(exch);
    199199       
     
    342342}
    343343
    344 int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
     344int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
    345345    unsigned int flags)
    346346{
     
    383383}
    384384
    385 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
     385static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
     386    size_t buf_size)
     387{
     388        async_exch_t *exch;
     389        ipc_call_t dreply;
     390        size_t act_size;
     391        sysarg_t dretval;
     392       
     393        exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
     394       
     395        ipc_call_t answer;
     396        aid_t req = async_send_1(exch, method, arg1, &answer);
     397        aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply);
     398        async_wait_for(dreq, &dretval);
     399       
     400        devman_exchange_end(exch);
     401       
     402        if (dretval != EOK) {
     403                async_wait_for(req, NULL);
     404                return dretval;
     405        }
     406       
     407        sysarg_t retval;
     408        async_wait_for(req, &retval);
     409       
     410        if (retval != EOK)
     411                return retval;
     412       
     413        act_size = IPC_GET_ARG2(dreply);
     414        assert(act_size <= buf_size - 1);
     415        buf[act_size] = '\0';
     416       
     417        return EOK;
     418}
     419
     420int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size)
     421{
     422        return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf,
     423            buf_size);
     424}
     425
     426int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size)
     427{
     428        return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf,
     429            buf_size);
     430}
     431
     432static int devman_get_handles_once(sysarg_t method, sysarg_t arg1,
     433    devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
     434{
     435        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     436
     437        ipc_call_t answer;
     438        aid_t req = async_send_1(exch, method, arg1, &answer);
     439        int rc = async_data_read_start(exch, handle_buf, buf_size);
     440       
     441        devman_exchange_end(exch);
     442       
     443        if (rc != EOK) {
     444                async_wait_for(req, NULL);
     445                return rc;
     446        }
     447       
     448        sysarg_t retval;
     449        async_wait_for(req, &retval);
     450       
     451        if (retval != EOK) {
     452                return retval;
     453        }
     454       
     455        *act_size = IPC_GET_ARG1(answer);
     456        return EOK;
     457}
     458
     459/** Get list of handles.
     460 *
     461 * Returns an allocated array of handles.
     462 *
     463 * @param method        IPC method
     464 * @param arg1          IPC argument 1
     465 * @param data          Place to store pointer to array of handles
     466 * @param count         Place to store number of handles
     467 * @return              EOK on success or negative error code
     468 */
     469static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1,
     470    devman_handle_t **data, size_t *count)
     471{
     472        devman_handle_t *handles;
     473        size_t act_size;
     474        size_t alloc_size;
     475        int rc;
     476
     477        *data = NULL;
     478        act_size = 0;   /* silence warning */
     479
     480        rc = devman_get_handles_once(method, arg1, NULL, 0,
     481            &act_size);
     482        if (rc != EOK)
     483                return rc;
     484
     485        alloc_size = act_size;
     486        handles = malloc(alloc_size);
     487        if (handles == NULL)
     488                return ENOMEM;
     489
     490        while (true) {
     491                rc = devman_get_handles_once(method, arg1, handles, alloc_size,
     492                    &act_size);
     493                if (rc != EOK)
     494                        return rc;
     495
     496                if (act_size <= alloc_size)
     497                        break;
     498
     499                alloc_size *= 2;
     500                free(handles);
     501
     502                handles = malloc(alloc_size);
     503                if (handles == NULL)
     504                        return ENOMEM;
     505        }
     506
     507        *count = act_size / sizeof(devman_handle_t);
     508        *data = handles;
     509        return EOK;
     510}
     511
     512int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
    386513{
    387514        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     
    389516                return ENOMEM;
    390517       
    391         ipc_call_t answer;
    392         aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
    393             handle, &answer);
    394        
    395         ipc_call_t data_request_call;
    396         aid_t data_request = async_data_read(exch, path, path_size,
    397             &data_request_call);
    398        
    399         devman_exchange_end(exch);
    400        
    401         if (data_request == 0) {
    402                 async_wait_for(req, NULL);
    403                 return ENOMEM;
    404         }
    405        
    406         sysarg_t data_request_rc;
    407         async_wait_for(data_request, &data_request_rc);
    408        
    409         sysarg_t opening_request_rc;
    410         async_wait_for(req, &opening_request_rc);
    411        
    412         if (data_request_rc != EOK) {
    413                 /* Prefer the return code of the opening request. */
    414                 if (opening_request_rc != EOK)
    415                         return (int) opening_request_rc;
    416                 else
    417                         return (int) data_request_rc;
    418         }
    419        
    420         if (opening_request_rc != EOK)
    421                 return (int) opening_request_rc;
    422        
    423         /* To be on the safe-side. */
    424         path[path_size - 1] = 0;
    425         size_t transferred_size = IPC_GET_ARG2(data_request_call);
    426         if (transferred_size >= path_size)
    427                 return ELIMIT;
    428        
    429         /* Terminate the string (trailing 0 not send over IPC). */
    430         path[transferred_size] = 0;
    431         return EOK;
     518        sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD,
     519            funh, devh);
     520       
     521        devman_exchange_end(exch);
     522        return (int) retval;
     523}
     524
     525int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs,
     526    size_t *count)
     527{
     528        return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS,
     529            devh, funcs, count);
    432530}
    433531
  • uspace/lib/c/generic/io/printf_core.c

    r1877128 rd1e196f7  
    206206        }
    207207       
    208         return (int) (counter + 1);
     208        return (int) (counter);
    209209}
    210210
     
    244244        }
    245245       
    246         return (int) (counter + 1);
     246        return (int) (counter);
    247247}
    248248
  • uspace/lib/c/generic/ipc.c

    r1877128 rd1e196f7  
    4747#include <futex.h>
    4848#include <fibril.h>
     49#include <macros.h>
    4950
    5051/**
     
    611612/** Request callback connection.
    612613 *
    613  * The @a taskhash and @a phonehash identifiers returned
     614 * The @a task_id and @a phonehash identifiers returned
    614615 * by the kernel can be used for connection tracking.
    615616 *
     
    618619 * @param arg2      User defined argument.
    619620 * @param arg3      User defined argument.
    620  * @param taskhash  Opaque identifier of the client task.
     621 * @param task_id   Identifier of the client task.
    621622 * @param phonehash Opaque identifier of the phone that will
    622623 *                  be used for incoming calls.
     
    626627 */
    627628int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    628     sysarg_t *taskhash, sysarg_t *phonehash)
    629 {
    630         return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
    631             arg3, NULL, NULL, NULL, taskhash, phonehash);
     629    task_id_t *task_id, sysarg_t *phonehash)
     630{
     631        ipc_call_t data;
     632        int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid,
     633            IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data);
     634        if (rc == EOK) {
     635                *task_id = data.in_task_id;
     636                *phonehash = IPC_GET_ARG5(data);
     637        }       
     638        return rc;
    632639}
    633640
  • uspace/lib/c/generic/loader.c

    r1877128 rd1e196f7  
    263263       
    264264        int i;
    265         for (i = 0; files[i]; i++)
    266                 ;
     265        for (i = 0; files[i]; i++);
    267266
    268267        ipc_call_t answer;
  • uspace/lib/c/generic/loc.c

    r1877128 rd1e196f7  
    315315/** Register new service.
    316316 *
    317  * @param fqsn  Fully qualified service name
    318  * @param sid   Output: ID of new service
     317 * @param fqsn Fully qualified service name
     318 * @param sid  Output: ID of new service
    319319 *
    320320 */
  • uspace/lib/c/generic/ns.c

    r1877128 rd1e196f7  
    5656        async_exchange_end(exch);
    5757       
     58        /*
     59         * FIXME Ugly hack to work around limitation of implementing
     60         * parallel exchanges using multiple connections. Shift out
     61         * first argument for non-initial connections.
     62         */
     63        async_sess_args_set(sess, arg2, arg3, 0);
     64       
    5865        return sess;
    5966}
     
    6673            async_connect_me_to_blocking(mgmt, exch, service, arg2, arg3);
    6774        async_exchange_end(exch);
     75       
     76        /*
     77         * FIXME Ugly hack to work around limitation of implementing
     78         * parallel exchanges using multiple connections. Shift out
     79         * first argument for non-initial connections.
     80         */
     81        async_sess_args_set(sess, arg2, arg3, 0);
    6882       
    6983        return sess;
  • uspace/lib/c/generic/private/async.h

    r1877128 rd1e196f7  
    3636#define LIBC_PRIVATE_ASYNC_H_
    3737
    38 #include <ipc/common.h>
     38#include <async.h>
    3939#include <adt/list.h>
    4040#include <fibril.h>
     41#include <fibril_synch.h>
    4142#include <sys/time.h>
    4243#include <bool.h>
     44
     45/** Session data */
     46struct _async_sess {
     47        /** List of inactive exchanges */
     48        list_t exch_list;
     49       
     50        /** Exchange management style */
     51        exch_mgmt_t mgmt;
     52       
     53        /** Session identification */
     54        int phone;
     55       
     56        /** First clone connection argument */
     57        sysarg_t arg1;
     58       
     59        /** Second clone connection argument */
     60        sysarg_t arg2;
     61       
     62        /** Third clone connection argument */
     63        sysarg_t arg3;
     64       
     65        /** Exchange mutex */
     66        fibril_mutex_t mutex;
     67       
     68        /** Number of opened exchanges */
     69        atomic_t refcnt;
     70       
     71        /** Mutex for stateful connections */
     72        fibril_mutex_t remote_state_mtx;
     73       
     74        /** Data for stateful connections */
     75        void *remote_state_data;
     76};
     77
     78/** Exchange data */
     79struct _async_exch {
     80        /** Link into list of inactive exchanges */
     81        link_t sess_link;
     82       
     83        /** Link into global list of inactive exchanges */
     84        link_t global_link;
     85       
     86        /** Session pointer */
     87        async_sess_t *sess;
     88       
     89        /** Exchange identification */
     90        int phone;
     91};
    4392
    4493/** Structures of this type are used to track the timeout events. */
  • uspace/lib/c/include/async.h

    r1877128 rd1e196f7  
    4242#include <ipc/common.h>
    4343#include <fibril.h>
    44 #include <fibril_synch.h>
    4544#include <sys/time.h>
    4645#include <atomic.h>
     
    9695} exch_mgmt_t;
    9796
    98 /** Session data */
    99 typedef struct {
    100         /** List of inactive exchanges */
    101         list_t exch_list;
    102        
    103         /** Exchange management style */
    104         exch_mgmt_t mgmt;
    105        
    106         /** Session identification */
    107         int phone;
    108        
    109         /** First clone connection argument */
    110         sysarg_t arg1;
    111        
    112         /** Second clone connection argument */
    113         sysarg_t arg2;
    114        
    115         /** Third clone connection argument */
    116         sysarg_t arg3;
    117        
    118         /** Exchange mutex */
    119         fibril_mutex_t mutex;
    120        
    121         /** Number of opened exchanges */
    122         atomic_t refcnt;
    123 } async_sess_t;
    124 
    125 /** Exchange data */
    126 typedef struct {
    127         /** Link into list of inactive exchanges */
    128         link_t sess_link;
    129        
    130         /** Link into global list of inactive exchanges */
    131         link_t global_link;
    132        
    133         /** Session pointer */
    134         async_sess_t *sess;
    135        
    136         /** Exchange identification */
    137         int phone;
    138 } async_exch_t;
     97/** Forward declarations */
     98struct _async_exch;
     99struct _async_sess;
     100
     101typedef struct _async_sess async_sess_t;
     102typedef struct _async_exch async_exch_t;
    139103
    140104extern atomic_t threads_in_ipc_wait;
     
    176140extern int async_wait_timeout(aid_t, sysarg_t *, suseconds_t);
    177141
    178 extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
     142extern fid_t async_new_connection(task_id_t, sysarg_t, ipc_callid_t,
    179143    ipc_call_t *, async_client_conn_t, void *);
    180144
     
    186150extern void async_set_client_data_destructor(async_client_data_dtor_t);
    187151extern void *async_get_client_data(void);
    188 extern void *async_get_client_data_by_hash(sysarg_t);
    189 extern void async_put_client_data_by_hash(sysarg_t);
     152extern void *async_get_client_data_by_id(task_id_t);
     153extern void async_put_client_data_by_id(task_id_t);
    190154
    191155extern void async_set_client_connection(async_client_conn_t);
     
    373337
    374338/*
     339 * FIXME These functions just work around problems with parallel exchange
     340 * management. Proper solution needs to be implemented.
     341 */
     342void async_sess_args_set(async_sess_t *sess, sysarg_t, sysarg_t, sysarg_t);
     343
     344/*
    375345 * User-friendly wrappers for async_share_in_start().
    376346 */
     
    485455extern int async_state_change_finalize(ipc_callid_t, async_exch_t *);
    486456
     457extern void *async_remote_state_acquire(async_sess_t *);
     458extern void async_remote_state_update(async_sess_t *, void *);
     459extern void async_remote_state_release(async_sess_t *);
     460extern void async_remote_state_release_exchange(async_exch_t *);
     461
    487462#endif
    488463
  • uspace/lib/c/include/devman.h

    r1877128 rd1e196f7  
    5656    unsigned int);
    5757
    58 extern int devman_device_get_handle(const char *, devman_handle_t *,
     58extern int devman_fun_get_handle(const char *, devman_handle_t *,
    5959    unsigned int);
    60 extern int devman_get_device_path(devman_handle_t, char *, size_t);
     60extern int devman_fun_get_child(devman_handle_t, devman_handle_t *);
     61extern int devman_dev_get_functions(devman_handle_t, devman_handle_t **,
     62    size_t *);
     63extern int devman_fun_get_name(devman_handle_t, char *, size_t);
     64extern int devman_fun_get_path(devman_handle_t, char *, size_t);
    6165
    6266extern int devman_add_device_to_category(devman_handle_t, const char *);
  • uspace/lib/c/include/ipc/common.h

    r1877128 rd1e196f7  
    3939#include <abi/ipc/ipc.h>
    4040#include <atomic.h>
     41#include <task.h>
    4142
    4243#define IPC_FLAG_BLOCKING  0x01
     
    4445typedef struct {
    4546        sysarg_t args[IPC_CALL_LEN];
    46         sysarg_t in_task_hash;
     47        task_id_t in_task_id;
    4748        sysarg_t in_phone_hash;
    4849} ipc_call_t;
  • uspace/lib/c/include/ipc/devman.h

    r1877128 rd1e196f7  
    149149typedef enum {
    150150        DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD,
    151         DEVMAN_DEVICE_GET_DEVICE_PATH,
     151        DEVMAN_DEV_GET_FUNCTIONS,
     152        DEVMAN_FUN_GET_CHILD,
     153        DEVMAN_FUN_GET_NAME,
     154        DEVMAN_FUN_GET_PATH,
    152155        DEVMAN_FUN_SID_TO_HANDLE
    153156} client_to_devman_t;
  • uspace/lib/c/include/ipc/ipc.h

    r1877128 rd1e196f7  
    254254    sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool);
    255255
    256 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t *,
     256extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *,
    257257    sysarg_t *);
    258258extern int ipc_connect_me(int);
  • uspace/lib/drv/generic/driver.c

    r1877128 rd1e196f7  
    428428static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    429429{
     430        sysarg_t conn_type;
     431
     432        if (iid == 0) {
     433                /* Callback connection from devman */
     434                /* XXX Use separate handler for this type of connection */
     435                conn_type = DRIVER_DEVMAN;
     436        } else {
     437                conn_type = IPC_GET_ARG1(*icall);
     438        }
     439
    430440        /* Select interface */
    431         switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
     441        switch (conn_type) {
    432442        case DRIVER_DEVMAN:
    433443                /* Handle request from device manager */
  • uspace/lib/usb/src/resolve.c

    r1877128 rd1e196f7  
    152152                if (str_length(func_start) > 0) {
    153153                        char tmp_path[MAX_DEVICE_PATH ];
    154                         rc = devman_get_device_path(dev_handle,
     154                        rc = devman_fun_get_path(dev_handle,
    155155                            tmp_path, MAX_DEVICE_PATH);
    156156                        if (rc != EOK) {
     
    173173
    174174        /* First try to get the device handle. */
    175         rc = devman_device_get_handle(path, &dev_handle, 0);
     175        rc = devman_fun_get_handle(path, &dev_handle, 0);
    176176        if (rc != EOK) {
    177177                free(path);
     
    184184                /* Get device handle first. */
    185185                devman_handle_t tmp_handle;
    186                 rc = devman_device_get_handle(path, &tmp_handle, 0);
     186                rc = devman_fun_get_handle(path, &tmp_handle, 0);
    187187                if (rc != EOK) {
    188188                        free(path);
  • uspace/lib/usbvirt/src/device.c

    r1877128 rd1e196f7  
    8787       
    8888        devman_handle_t handle;
    89         int rc = devman_device_get_handle(vhc_path, &handle, 0);
     89        int rc = devman_fun_get_handle(vhc_path, &handle, 0);
    9090        if (rc != EOK)
    9191                return rc;
  • uspace/srv/devman/devman.c

    r1877128 rd1e196f7  
    548548
    549549        fibril_mutex_lock(&driver->driver_mutex);
    550        
    551         async_exch_t *exch = async_exchange_begin(driver->sess);
    552         async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    553             DRIVER_DEVMAN, 0, 0);
    554         async_exchange_end(exch);
    555 
    556         if (!sess) {
    557                 fibril_mutex_unlock(&driver->driver_mutex);
    558                 return;
    559         }
    560550
    561551        /*
     
    583573                fibril_mutex_unlock(&driver->driver_mutex);
    584574
    585                 add_device(sess, driver, dev, tree);
     575                add_device(driver, dev, tree);
    586576
    587577                /*
     
    603593                link = driver->devices.head.next;
    604594        }
    605 
    606         async_hangup(sess);
    607595
    608596        /*
     
    718706 * @param node          The device's node in the device tree.
    719707 */
    720 void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev,
    721     dev_tree_t *tree)
     708void add_device(driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
    722709{
    723710        /*
     
    736723        }
    737724       
    738         async_exch_t *exch = async_exchange_begin(sess);
     725        async_exch_t *exch = async_exchange_begin(drv->sess);
    739726       
    740727        ipc_call_t answer;
     
    806793        fibril_mutex_unlock(&drv->driver_mutex);
    807794
    808         if (is_running) {
    809                 /* Notify the driver about the new device. */
    810                 async_exch_t *exch = async_exchange_begin(drv->sess);
    811                 async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
    812                     DRIVER_DEVMAN, 0, 0);
    813                 async_exchange_end(exch);
    814                
    815                 if (sess) {
    816                         add_device(sess, drv, dev, tree);
    817                         async_hangup(sess);
    818                 }
    819         }
     795        /* Notify the driver about the new device. */
     796        if (is_running)
     797                add_device(drv, dev, tree);
    820798       
    821799        return true;
     
    919897        return dev;
    920898}
     899
     900/** Get list of device functions. */
     901int dev_get_functions(dev_tree_t *tree, dev_node_t *dev,
     902    devman_handle_t *hdl_buf, size_t buf_size, size_t *act_size)
     903{
     904        size_t act_cnt;
     905        size_t buf_cnt;
     906
     907        assert(fibril_rwlock_is_locked(&tree->rwlock));
     908
     909        buf_cnt = buf_size / sizeof(devman_handle_t);
     910
     911        act_cnt = list_count(&dev->functions);
     912        *act_size = act_cnt * sizeof(devman_handle_t);
     913
     914        if (buf_size % sizeof(devman_handle_t) != 0)
     915                return EINVAL;
     916
     917        size_t pos = 0;
     918        list_foreach(dev->functions, item) {
     919                fun_node_t *fun =
     920                    list_get_instance(item, fun_node_t, dev_functions);
     921
     922                if (pos < buf_cnt)
     923                        hdl_buf[pos] = fun->handle;
     924                pos++;
     925        }
     926
     927        return EOK;
     928}
     929
    921930
    922931/* Function nodes */
     
    11451154        char *rel_path = path;
    11461155        char *next_path_elem = NULL;
    1147         bool cont = true;
     1156        bool cont = (rel_path[1] != '\0');
    11481157       
    11491158        while (cont && fun != NULL) {
  • uspace/srv/devman/devman.h

    r1877128 rd1e196f7  
    6363typedef struct fun_node fun_node_t;
    6464
     65typedef struct {
     66        fibril_mutex_t mutex;
     67        struct driver *driver;
     68} client_t;
     69
    6570typedef enum {
    6671        /** Driver has not been started. */
     
    235240extern void add_driver(driver_list_t *, driver_t *);
    236241extern void attach_driver(dev_node_t *, driver_t *);
    237 extern void add_device(async_sess_t *, driver_t *, dev_node_t *, dev_tree_t *);
     242extern void add_device(driver_t *, dev_node_t *, dev_tree_t *);
    238243extern bool start_driver(driver_t *);
    239244
     
    253258extern dev_node_t *find_dev_node(dev_tree_t *tree, devman_handle_t handle);
    254259extern dev_node_t *find_dev_function(dev_node_t *, const char *);
     260extern int dev_get_functions(dev_tree_t *tree, dev_node_t *, devman_handle_t *,
     261    size_t, size_t *);
    255262
    256263extern fun_node_t *create_fun_node(void);
  • uspace/srv/devman/main.c

    r1877128 rd1e196f7  
    6565static dev_tree_t device_tree;
    6666
     67static int init_running_drv(void *drv);
     68
    6769/** Register running driver. */
    68 static driver_t *devman_driver_register(void)
    69 {
    70         ipc_call_t icall;
    71         ipc_callid_t iid;
     70static driver_t *devman_driver_register(ipc_callid_t callid, ipc_call_t *call)
     71{
    7272        driver_t *driver = NULL;
     73        char *drv_name = NULL;
    7374
    7475        log_msg(LVL_DEBUG, "devman_driver_register");
    75        
    76         iid = async_get_call(&icall);
    77         if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) {
    78                 async_answer_0(iid, EREFUSED);
    79                 return NULL;
    80         }
    81        
    82         char *drv_name = NULL;
    8376       
    8477        /* Get driver name. */
    8578        int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);
    8679        if (rc != EOK) {
    87                 async_answer_0(iid, rc);
     80                async_answer_0(callid, rc);
    8881                return NULL;
    8982        }
     
    9891                free(drv_name);
    9992                drv_name = NULL;
    100                 async_answer_0(iid, ENOENT);
     93                async_answer_0(callid, ENOENT);
    10194                return NULL;
    10295        }
     
    112105                    driver->name);
    113106                fibril_mutex_unlock(&driver->driver_mutex);
    114                 async_answer_0(iid, EEXISTS);
     107                async_answer_0(callid, EEXISTS);
    115108                return NULL;
    116109        }
     
    134127        log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.",
    135128            driver->name);
    136         driver->sess = async_callback_receive(EXCHANGE_SERIALIZE);
     129        driver->sess = async_callback_receive(EXCHANGE_PARALLEL);
    137130        if (!driver->sess) {
    138131                fibril_mutex_unlock(&driver->driver_mutex);
    139                 async_answer_0(iid, ENOTSUP);
     132                async_answer_0(callid, ENOTSUP);
    140133                return NULL;
    141134        }
    142        
    143         fibril_mutex_unlock(&driver->driver_mutex);
     135        /* FIXME: Work around problem with callback sessions */
     136        async_sess_args_set(driver->sess, DRIVER_DEVMAN, 0, 0);
    144137       
    145138        log_msg(LVL_NOTE,
     
    147140            driver->name);
    148141       
    149         async_answer_0(iid, EOK);
    150        
     142        /*
     143         * Initialize the driver as running (e.g. pass assigned devices to it)
     144         * in a separate fibril; the separate fibril is used to enable the
     145         * driver to use devman service during the driver's initialization.
     146         */
     147        fid_t fid = fibril_create(init_running_drv, driver);
     148        if (fid == 0) {
     149                log_msg(LVL_ERROR, "Failed to create initialization fibril " \
     150                    "for driver `%s'.", driver->name);
     151                fibril_mutex_unlock(&driver->driver_mutex);
     152                async_answer_0(callid, ENOMEM);
     153                return NULL;
     154        }
     155       
     156        fibril_add_ready(fid);
     157        fibril_mutex_unlock(&driver->driver_mutex);
     158       
     159        async_answer_0(callid, EOK);
    151160        return driver;
    152161}
     
    429438static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
    430439{
     440        client_t *client;
     441        driver_t *driver;
     442       
    431443        /* Accept the connection. */
    432444        async_answer_0(iid, EOK);
    433445       
    434         driver_t *driver = devman_driver_register();
    435         if (driver == NULL)
    436                 return;
    437        
    438         /*
    439          * Initialize the driver as running (e.g. pass assigned devices to it)
    440          * in a separate fibril; the separate fibril is used to enable the
    441          * driver to use devman service during the driver's initialization.
    442          */
    443         fid_t fid = fibril_create(init_running_drv, driver);
    444         if (fid == 0) {
    445                 log_msg(LVL_ERROR, "Failed to create initialization fibril " \
    446                     "for driver `%s'.", driver->name);
    447                 return;
    448         }
    449         fibril_add_ready(fid);
     446        client = async_get_client_data();
     447        if (client == NULL) {
     448                log_msg(LVL_ERROR, "Failed to allocate client data.");
     449                return;
     450        }
    450451       
    451452        while (true) {
     
    456457                        break;
    457458               
     459                if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) {
     460                        fibril_mutex_lock(&client->mutex);
     461                        driver = client->driver;
     462                        fibril_mutex_unlock(&client->mutex);
     463                        if (driver == NULL) {
     464                                /* First call must be to DEVMAN_DRIVER_REGISTER */
     465                                async_answer_0(callid, ENOTSUP);
     466                                continue;
     467                        }
     468                }
     469               
    458470                switch (IPC_GET_IMETHOD(call)) {
     471                case DEVMAN_DRIVER_REGISTER:
     472                        fibril_mutex_lock(&client->mutex);
     473                        if (client->driver != NULL) {
     474                                fibril_mutex_unlock(&client->mutex);
     475                                async_answer_0(callid, EINVAL);
     476                                continue;
     477                        }
     478                        client->driver = devman_driver_register(callid, &call);
     479                        fibril_mutex_unlock(&client->mutex);
     480                        break;
    459481                case DEVMAN_ADD_FUNCTION:
    460482                        devman_add_function(callid, &call);
     
    497519}
    498520
    499 /** Find device path by its handle. */
    500 static void devman_get_device_path_by_handle(ipc_callid_t iid,
    501     ipc_call_t *icall)
     521/** Get device name. */
     522static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall)
    502523{
    503524        devman_handle_t handle = IPC_GET_ARG1(*icall);
     
    523544        }
    524545
     546        size_t sent_length = str_size(fun->name);
     547        if (sent_length > data_len) {
     548                sent_length = data_len;
     549        }
     550
     551        async_data_read_finalize(data_callid, fun->name, sent_length);
     552        async_answer_0(iid, EOK);
     553
     554        free(buffer);
     555}
     556
     557
     558/** Get device path. */
     559static void devman_fun_get_path(ipc_callid_t iid, ipc_call_t *icall)
     560{
     561        devman_handle_t handle = IPC_GET_ARG1(*icall);
     562
     563        fun_node_t *fun = find_fun_node(&device_tree, handle);
     564        if (fun == NULL) {
     565                async_answer_0(iid, ENOMEM);
     566                return;
     567        }
     568
     569        ipc_callid_t data_callid;
     570        size_t data_len;
     571        if (!async_data_read_receive(&data_callid, &data_len)) {
     572                async_answer_0(iid, EINVAL);
     573                return;
     574        }
     575
     576        void *buffer = malloc(data_len);
     577        if (buffer == NULL) {
     578                async_answer_0(data_callid, ENOMEM);
     579                async_answer_0(iid, ENOMEM);
     580                return;
     581        }
     582
    525583        size_t sent_length = str_size(fun->pathname);
    526584        if (sent_length > data_len) {
     
    532590
    533591        free(buffer);
     592}
     593
     594static void devman_dev_get_functions(ipc_callid_t iid, ipc_call_t *icall)
     595{
     596        ipc_callid_t callid;
     597        size_t size;
     598        size_t act_size;
     599        int rc;
     600       
     601        if (!async_data_read_receive(&callid, &size)) {
     602                async_answer_0(callid, EREFUSED);
     603                async_answer_0(iid, EREFUSED);
     604                return;
     605        }
     606       
     607        fibril_rwlock_read_lock(&device_tree.rwlock);
     608       
     609        dev_node_t *dev = find_dev_node_no_lock(&device_tree,
     610            IPC_GET_ARG1(*icall));
     611        if (dev == NULL) {
     612                fibril_rwlock_read_unlock(&device_tree.rwlock);
     613                async_answer_0(callid, ENOENT);
     614                async_answer_0(iid, ENOENT);
     615                return;
     616        }
     617       
     618        devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
     619        if (hdl_buf == NULL) {
     620                fibril_rwlock_read_unlock(&device_tree.rwlock);
     621                async_answer_0(callid, ENOMEM);
     622                async_answer_0(iid, ENOMEM);
     623                return;
     624        }
     625       
     626        rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size);
     627        if (rc != EOK) {
     628                fibril_rwlock_read_unlock(&device_tree.rwlock);
     629                async_answer_0(callid, rc);
     630                async_answer_0(iid, rc);
     631                return;
     632        }
     633       
     634        fibril_rwlock_read_unlock(&device_tree.rwlock);
     635       
     636        sysarg_t retval = async_data_read_finalize(callid, hdl_buf, size);
     637        free(hdl_buf);
     638       
     639        async_answer_1(iid, retval, act_size);
     640}
     641
     642
     643/** Get handle for child device of a function. */
     644static void devman_fun_get_child(ipc_callid_t iid, ipc_call_t *icall)
     645{
     646        fun_node_t *fun;
     647       
     648        fibril_rwlock_read_lock(&device_tree.rwlock);
     649       
     650        fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
     651        if (fun == NULL) {
     652                fibril_rwlock_read_unlock(&device_tree.rwlock);
     653                async_answer_0(iid, ENOENT);
     654                return;
     655        }
     656       
     657        if (fun->child == NULL) {
     658                fibril_rwlock_read_unlock(&device_tree.rwlock);
     659                async_answer_0(iid, ENOENT);
     660                return;
     661        }
     662       
     663        async_answer_1(iid, EOK, fun->child->handle);
     664       
     665        fibril_rwlock_read_unlock(&device_tree.rwlock);
    534666}
    535667
     
    566698                        devman_function_get_handle(callid, &call);
    567699                        break;
    568                 case DEVMAN_DEVICE_GET_DEVICE_PATH:
    569                         devman_get_device_path_by_handle(callid, &call);
     700                case DEVMAN_DEV_GET_FUNCTIONS:
     701                        devman_dev_get_functions(callid, &call);
     702                        break;
     703                case DEVMAN_FUN_GET_CHILD:
     704                        devman_fun_get_child(callid, &call);
     705                        break;
     706                case DEVMAN_FUN_GET_NAME:
     707                        devman_fun_get_name(callid, &call);
     708                        break;
     709                case DEVMAN_FUN_GET_PATH:
     710                        devman_fun_get_path(callid, &call);
    570711                        break;
    571712                case DEVMAN_FUN_SID_TO_HANDLE:
     
    695836static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    696837{
    697         /* Select interface. */
     838        /* Select port. */
    698839        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
    699840        case DEVMAN_DRIVER:
     
    721862}
    722863
     864static void *devman_client_data_create(void)
     865{
     866        client_t *client;
     867       
     868        client = calloc(1, sizeof(client_t));
     869        if (client == NULL)
     870                return NULL;
     871       
     872        fibril_mutex_initialize(&client->mutex);
     873        return client;
     874}
     875
     876static void devman_client_data_destroy(void *data)
     877{
     878        free(data);
     879}
     880
    723881/** Initialize device manager internal structures. */
    724882static bool devman_init(void)
     
    767925        }
    768926       
    769         /* Set a handler of incomming connections. */
     927        /* Set handlers for incoming connections. */
     928        async_set_client_data_constructor(devman_client_data_create);
     929        async_set_client_data_destructor(devman_client_data_destroy);
    770930        async_set_client_connection(devman_connection);
    771931
  • uspace/srv/vfs/vfs.c

    r1877128 rd1e196f7  
    3636 */
    3737
     38#include <vfs/vfs.h>
    3839#include <ipc/services.h>
    3940#include <abi/ipc/event.h>
     
    4748#include <as.h>
    4849#include <atomic.h>
    49 #include <vfs/vfs.h>
     50#include <macros.h>
    5051#include "vfs.h"
    5152
    5253#define NAME  "vfs"
     54
     55enum {
     56        VFS_TASK_STATE_CHANGE
     57};
    5358
    5459static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     
    134139}
    135140
    136 enum {
    137         VFS_TASK_STATE_CHANGE
    138 };
    139 
    140141static void notification_received(ipc_callid_t callid, ipc_call_t *call)
    141142{
     
    143144        case VFS_TASK_STATE_CHANGE:
    144145                if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
    145                         vfs_pass_handle(IPC_GET_ARG4(*call),
    146                             IPC_GET_ARG5(*call), (int) IPC_GET_ARG2(*call));
     146                        vfs_pass_handle(
     147                            (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
     148                            IPC_GET_ARG5(*call)), call->in_task_id,
     149                            (int) IPC_GET_ARG2(*call));
    147150                break;
    148151        default:
  • uspace/srv/vfs/vfs.h

    r1877128 rd1e196f7  
    4141#include <bool.h>
    4242#include <ipc/vfs.h>
     43#include <task.h>
    4344
    4445#ifndef dprintf
     
    188189extern void vfs_client_data_destroy(void *);
    189190
    190 extern void vfs_pass_handle(sysarg_t, sysarg_t, int);
     191extern void vfs_pass_handle(task_id_t, task_id_t, int);
    191192extern int vfs_wait_handle_internal(void);
    192193
  • uspace/srv/vfs/vfs_file.c

    r1877128 rd1e196f7  
    4444#include <fibril_synch.h>
    4545#include <adt/list.h>
     46#include <task.h>
    4647#include "vfs.h"
    4748
     
    346347}
    347348
    348 void vfs_pass_handle(sysarg_t donor_hash, sysarg_t acceptor_hash, int donor_fd)
     349void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd)
    349350{
    350351        vfs_client_data_t *donor_data = NULL;
     
    355356        int acceptor_fd;
    356357
    357         acceptor_data = async_get_client_data_by_hash(acceptor_hash);
     358        acceptor_data = async_get_client_data_by_id(acceptor_id);
    358359        if (!acceptor_data)
    359360                return;
     
    365366        bh->handle = -1;
    366367
    367         donor_data = async_get_client_data_by_hash(donor_hash);
     368        donor_data = async_get_client_data_by_id(donor_id);
    368369        if (!donor_data)
    369370                goto out;
     
    402403
    403404        if (donor_data)
    404                 async_put_client_data_by_hash(donor_hash);
     405                async_put_client_data_by_id(donor_id);
    405406        if (acceptor_data)
    406                 async_put_client_data_by_hash(acceptor_hash);
     407                async_put_client_data_by_id(acceptor_id);
    407408        if (donor_file)
    408409                _vfs_file_put(donor_data, donor_file);
Note: See TracChangeset for help on using the changeset viewer.