Ignore:
File:
1 edited

Legend:

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

    re6211f8 re72fb34  
    3636
    3737#include <str.h>
     38#include <stdio.h>
    3839#include <ipc/services.h>
    39 #include <ns.h>
    4040#include <ipc/devman.h>
    4141#include <devman.h>
     42#include <async.h>
    4243#include <fibril_synch.h>
    43 #include <async.h>
    4444#include <errno.h>
    4545#include <malloc.h>
    4646#include <bool.h>
    47 
    48 static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex);
    49 static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex);
    50 
    51 static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex);
    52 static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex);
    53 
    54 static async_sess_t *devman_driver_block_sess = NULL;
    55 static async_sess_t *devman_client_block_sess = NULL;
    56 
    57 static async_sess_t *devman_driver_sess = NULL;
    58 static async_sess_t *devman_client_sess = NULL;
    59 
    60 static 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  */
    78 async_exch_t *devman_exchange_begin_blocking(devman_interface_t iface)
     47#include <adt/list.h>
     48
     49static int devman_phone_driver = -1;
     50static int devman_phone_client = -1;
     51
     52static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
     53
     54int devman_get_phone(devman_interface_t iface, unsigned int flags)
    7955{
    8056        switch (iface) {
    8157        case DEVMAN_DRIVER:
    82                 fibril_mutex_lock(&devman_driver_block_mutex);
     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;
     62                }
    8363               
    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);
    92                 }
     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);
    9370               
    94                 fibril_mutex_unlock(&devman_driver_block_mutex);
     71                fibril_mutex_unlock(&devman_phone_mutex);
     72                return devman_phone_driver;
     73        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;
     78                }
    9579               
    96                 clone_session(&devman_driver_mutex, devman_driver_block_sess,
    97                     &devman_driver_sess);
     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                }
    9887               
    99                 return async_exchange_begin(devman_driver_block_sess);
    100         case DEVMAN_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);
    111                 }
    112                
    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);
     88                fibril_mutex_unlock(&devman_phone_mutex);
     89                return devman_phone_client;
    11990        default:
    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  */
    131 async_exch_t *devman_exchange_begin(devman_interface_t iface)
     91                return -1;
     92        }
     93}
     94
     95/** Register running driver with device manager. */
     96int devman_driver_register(const char *name, async_client_conn_t conn)
     97{
     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;
     113        }
     114       
     115        async_set_client_connection(conn);
     116       
     117        async_connect_to_me(phone, 0, 0, 0, NULL);
     118        async_wait_for(req, &retval);
     119       
     120        async_serialize_end();
     121       
     122        return retval;
     123}
     124
     125static 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
     139static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
     140{
     141        link_t *link = match_ids->ids.next;
     142        match_id_t *match_id = NULL;
     143        int ret = EOK;
     144
     145        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;
     150                }
     151
     152                link = link->next;
     153        }
     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 */
     171int 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;
     214}
     215
     216int devman_add_device_to_class(devman_handle_t devman_handle,
     217    const char *class_name)
     218{
     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,
     227            devman_handle, &answer);
     228       
     229        sysarg_t retval = async_data_write_start(phone, class_name,
     230            str_size(class_name));
     231        if (retval != EOK) {
     232                async_wait_for(req, NULL);
     233                async_serialize_end();
     234                return retval;
     235        }
     236       
     237        async_wait_for(req, &retval);
     238        async_serialize_end();
     239       
     240        return retval;
     241}
     242
     243void devman_hangup_phone(devman_interface_t iface)
    132244{
    133245        switch (iface) {
    134246        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);
     247                if (devman_phone_driver >= 0) {
     248                        async_hangup(devman_phone_driver);
     249                        devman_phone_driver = -1;
     250                }
     251                break;
    148252        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);
     253                if (devman_phone_client >= 0) {
     254                        async_hangup(devman_phone_client);
     255                        devman_phone_client = -1;
     256                }
     257                break;
    162258        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  */
    172 void devman_exchange_end(async_exch_t *exch)
    173 {
    174         async_exchange_end(exch);
    175 }
    176 
    177 /** Register running driver with device manager. */
    178 int devman_driver_register(const char *name, async_client_conn_t conn)
    179 {
    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;
    191         }
    192        
    193         async_set_client_connection(conn);
    194        
    195         exch = devman_exchange_begin(DEVMAN_DRIVER);
    196         async_connect_to_me(exch, 0, 0, 0, NULL);
    197         devman_exchange_end(exch);
    198        
    199         async_wait_for(req, &retval);
    200         return retval;
    201 }
    202 
    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  */
    217 int 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         link_t *link = match_ids->ids.next;
    234         match_id_t *match_id = NULL;
    235        
    236         while (link != &match_ids->ids) {
    237                 match_id = list_get_instance(link, match_id_t, link);
    238                
    239                 ipc_call_t answer2;
    240                 aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
    241                     match_id->score, &answer2);
    242                 retval = async_data_write_start(exch, match_id->id,
    243                     str_size(match_id->id));
    244                 if (retval != EOK) {
    245                         devman_exchange_end(exch);
    246                         async_wait_for(req2, NULL);
    247                         async_wait_for(req, NULL);
    248                         return retval;
    249                 }
    250                
    251                 async_wait_for(req2, &retval);
    252                 if (retval != EOK) {
    253                         devman_exchange_end(exch);
    254                         async_wait_for(req, NULL);
    255                         return retval;
    256                 }
    257                
    258                 link = link->next;
    259         }
    260        
    261         devman_exchange_end(exch);
    262        
    263         async_wait_for(req, &retval);
    264         if (retval == EOK) {
    265                 if (funh != NULL)
    266                         *funh = (int) IPC_GET_ARG1(answer);
     259                break;
     260        }
     261}
     262
     263int 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);
    267270        } else {
    268                 if (funh != NULL)
    269                         *funh = -1;
    270         }
    271        
    272         return retval;
    273 }
    274 
    275 int devman_add_device_to_class(devman_handle_t devman_handle,
    276     const char *class_name)
    277 {
    278         async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    279        
    280         ipc_call_t answer;
    281         aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
    282             devman_handle, &answer);
    283         sysarg_t retval = async_data_write_start(exch, class_name,
    284             str_size(class_name));
    285        
    286         devman_exchange_end(exch);
    287        
    288         if (retval != EOK) {
    289                 async_wait_for(req, NULL);
    290                 return retval;
    291         }
    292        
    293         async_wait_for(req, &retval);
    294         return retval;
    295 }
    296 
    297 async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle,
    298     unsigned int flags)
    299 {
    300         async_sess_t *sess;
    301        
    302         if (flags & IPC_FLAG_BLOCKING)
    303                 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
    304                             DEVMAN_CONNECT_TO_DEVICE, handle);
    305         else
    306                 sess = service_connect(mgmt, SERVICE_DEVMAN,
    307                             DEVMAN_CONNECT_TO_DEVICE, handle);
    308        
    309         return sess;
    310 }
    311 
    312 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    313     devman_handle_t handle, unsigned int flags)
    314 {
    315         async_sess_t *sess;
    316        
    317         if (flags & IPC_FLAG_BLOCKING)
    318                 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
    319                             DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    320         else
    321                 sess = service_connect(mgmt, SERVICE_DEVMAN,
    322                             DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    323        
    324         return sess;
     271                phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
     272                    DEVMAN_CONNECT_TO_DEVICE, handle);
     273        }
     274       
     275        return phone;
     276}
     277
     278int 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;
    325291}
    326292
     
    328294    unsigned int flags)
    329295{
    330         async_exch_t *exch;
    331        
    332         if (flags & IPC_FLAG_BLOCKING)
    333                 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
    334         else {
    335                 exch = devman_exchange_begin(DEVMAN_CLIENT);
    336                 if (exch == NULL)
    337                         return errno;
    338         }
    339        
    340         ipc_call_t answer;
    341         aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
     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,
    342305            &answer);
    343         sysarg_t retval = async_data_write_start(exch, pathname,
     306       
     307        sysarg_t retval = async_data_write_start(phone, pathname,
    344308            str_size(pathname));
    345        
    346         devman_exchange_end(exch);
    347        
    348         if (retval != EOK) {
    349                 async_wait_for(req, NULL);
    350                 return retval;
    351         }
    352        
    353         async_wait_for(req, &retval);
     309        if (retval != EOK) {
     310                async_wait_for(req, NULL);
     311                async_serialize_end();
     312                return retval;
     313        }
     314       
     315        async_wait_for(req, &retval);
     316       
     317        async_serialize_end();
    354318       
    355319        if (retval != EOK) {
    356320                if (handle != NULL)
    357321                        *handle = (devman_handle_t) -1;
    358                
    359322                return retval;
    360323        }
     
    369332    const char *devname, devman_handle_t *handle, unsigned int flags)
    370333{
    371         async_exch_t *exch;
    372        
    373         if (flags & IPC_FLAG_BLOCKING)
    374                 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
    375         else {
    376                 exch = devman_exchange_begin(DEVMAN_CLIENT);
    377                 if (exch == NULL)
    378                         return errno;
    379         }
    380        
    381         ipc_call_t answer;
    382         aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     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,
    383343            flags, &answer);
    384         sysarg_t retval = async_data_write_start(exch, classname,
     344
     345        sysarg_t retval = async_data_write_start(phone, classname,
    385346            str_size(classname));
    386        
    387         if (retval != EOK) {
    388                 devman_exchange_end(exch);
    389                 async_wait_for(req, NULL);
    390                 return retval;
    391         }
    392        
    393         retval = async_data_write_start(exch, devname,
     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,
    394353            str_size(devname));
    395        
    396         devman_exchange_end(exch);
    397        
    398         if (retval != EOK) {
    399                 async_wait_for(req, NULL);
    400                 return retval;
    401         }
    402        
    403         async_wait_for(req, &retval);
    404        
     354        if (retval != EOK) {
     355                async_wait_for(req, NULL);
     356                async_serialize_end();
     357                return retval;
     358        }
     359
     360        async_wait_for(req, &retval);
     361
     362        async_serialize_end();
     363
    405364        if (retval != EOK) {
    406365                if (handle != NULL)
    407366                        *handle = (devman_handle_t) -1;
    408                
    409                 return retval;
    410         }
    411        
     367                return retval;
     368        }
     369
    412370        if (handle != NULL)
    413371                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
    414        
    415         return retval;
    416 }
    417 
    418 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    419 {
    420         async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    421         if (exch == NULL)
    422                 return errno;
    423        
    424         ipc_call_t answer;
    425         aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
    426             handle, &answer);
    427        
    428         ipc_call_t data_request_call;
    429         aid_t data_request = async_data_read(exch, path, path_size,
    430             &data_request_call);
    431        
    432         devman_exchange_end(exch);
    433        
    434         if (data_request == 0) {
    435                 async_wait_for(req, NULL);
    436                 return ENOMEM;
    437         }
    438        
    439         sysarg_t data_request_rc;
    440         async_wait_for(data_request, &data_request_rc);
    441        
    442         sysarg_t opening_request_rc;
    443         async_wait_for(req, &opening_request_rc);
    444        
    445         if (data_request_rc != EOK) {
    446                 /* Prefer the return code of the opening request. */
    447                 if (opening_request_rc != EOK)
    448                         return (int) opening_request_rc;
    449                 else
    450                         return (int) data_request_rc;
    451         }
    452        
    453         if (opening_request_rc != EOK)
    454                 return (int) opening_request_rc;
    455        
    456         /* To be on the safe-side. */
    457         path[path_size - 1] = 0;
    458         size_t transferred_size = IPC_GET_ARG2(data_request_call);
    459         if (transferred_size >= path_size)
    460                 return ELIMIT;
    461        
    462         /* Terminate the string (trailing 0 not send over IPC). */
    463         path[transferred_size] = 0;
    464         return EOK;
    465 }
     372
     373        return retval;
     374}
     375
    466376
    467377/** @}
Note: See TracChangeset for help on using the changeset viewer.