Ignore:
File:
1 edited

Legend:

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

    r79ae36dd 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         async_wait_for(req, &retval);
    234         if (retval != EOK) {
    235                 devman_exchange_end(exch);
    236                
    237                 if (funh != NULL)
    238                         *funh = -1;
    239                
    240                 return retval;
    241         }
    242        
    243         if (funh != NULL)
    244                 *funh = (int) IPC_GET_ARG1(answer);
    245        
    246         link_t *link = match_ids->ids.next;
    247         match_id_t *match_id = NULL;
    248        
    249         while (link != &match_ids->ids) {
    250                 match_id = list_get_instance(link, match_id_t, link);
    251                
    252                 ipc_call_t answer;
    253                 aid_t req = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
    254                     match_id->score, &answer);
    255                 retval = async_data_write_start(exch, match_id->id,
    256                     str_size(match_id->id));
    257                 if (retval != EOK) {
    258                         devman_exchange_end(exch);
    259                         async_wait_for(req, NULL);
    260                         return retval;
    261                 }
    262                
    263                 async_wait_for(req, &retval);
    264                 if (retval != EOK) {
    265                         devman_exchange_end(exch);
    266                         return retval;
    267                 }
    268                
    269                 link = link->next;
    270         }
    271        
    272         devman_exchange_end(exch);
    273         return EOK;
    274 }
    275 
    276 int devman_add_device_to_class(devman_handle_t devman_handle,
    277     const char *class_name)
    278 {
    279         async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    280        
    281         ipc_call_t answer;
    282         aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
    283             devman_handle, &answer);
    284         sysarg_t retval = async_data_write_start(exch, class_name,
    285             str_size(class_name));
    286        
    287         devman_exchange_end(exch);
    288        
    289         if (retval != EOK) {
    290                 async_wait_for(req, NULL);
    291                 return retval;
    292         }
    293        
    294         async_wait_for(req, &retval);
    295         return retval;
    296 }
    297 
    298 async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle,
    299     unsigned int flags)
    300 {
    301         async_sess_t *sess;
    302        
    303         if (flags & IPC_FLAG_BLOCKING)
    304                 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
    305                             DEVMAN_CONNECT_TO_DEVICE, handle);
    306         else
    307                 sess = service_connect(mgmt, SERVICE_DEVMAN,
    308                             DEVMAN_CONNECT_TO_DEVICE, handle);
    309        
    310         return sess;
    311 }
    312 
    313 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    314     devman_handle_t handle, unsigned int flags)
    315 {
    316         async_sess_t *sess;
    317        
    318         if (flags & IPC_FLAG_BLOCKING)
    319                 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
    320                             DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    321         else
    322                 sess = service_connect(mgmt, SERVICE_DEVMAN,
    323                             DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
    324        
    325         return sess;
     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);
     270        } else {
     271                phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
     272                    DEVMAN_CONNECT_TO_DEVICE, handle);
     273        }
     274       
     275        return phone;
     276}
     277
     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;
    326291}
    327292
     
    329294    unsigned int flags)
    330295{
    331         async_exch_t *exch;
    332        
    333         if (flags & IPC_FLAG_BLOCKING)
    334                 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
    335         else {
    336                 exch = devman_exchange_begin(DEVMAN_CLIENT);
    337                 if (exch == NULL)
    338                         return errno;
    339         }
    340        
    341         ipc_call_t answer;
    342         aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
     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,
    343305            &answer);
    344         sysarg_t retval = async_data_write_start(exch, pathname,
     306       
     307        sysarg_t retval = async_data_write_start(phone, pathname,
    345308            str_size(pathname));
    346        
    347         devman_exchange_end(exch);
    348        
    349         if (retval != EOK) {
    350                 async_wait_for(req, NULL);
    351                 return retval;
    352         }
    353        
    354         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();
    355318       
    356319        if (retval != EOK) {
    357320                if (handle != NULL)
    358321                        *handle = (devman_handle_t) -1;
    359                
    360322                return retval;
    361323        }
     
    370332    const char *devname, devman_handle_t *handle, unsigned int flags)
    371333{
    372         async_exch_t *exch;
    373        
    374         if (flags & IPC_FLAG_BLOCKING)
    375                 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
    376         else {
    377                 exch = devman_exchange_begin(DEVMAN_CLIENT);
    378                 if (exch == NULL)
    379                         return errno;
    380         }
    381        
    382         ipc_call_t answer;
    383         aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     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,
    384343            flags, &answer);
    385         sysarg_t retval = async_data_write_start(exch, classname,
     344
     345        sysarg_t retval = async_data_write_start(phone, classname,
    386346            str_size(classname));
    387        
    388         if (retval != EOK) {
    389                 devman_exchange_end(exch);
    390                 async_wait_for(req, NULL);
    391                 return retval;
    392         }
    393        
    394         retval = async_data_write_start(exch, devname,
     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,
    395353            str_size(devname));
    396        
    397         devman_exchange_end(exch);
    398        
    399         if (retval != EOK) {
    400                 async_wait_for(req, NULL);
    401                 return retval;
    402         }
    403        
    404         async_wait_for(req, &retval);
    405        
     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
    406364        if (retval != EOK) {
    407365                if (handle != NULL)
    408366                        *handle = (devman_handle_t) -1;
    409                
    410                 return retval;
    411         }
    412        
     367                return retval;
     368        }
     369
    413370        if (handle != NULL)
    414371                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
    415        
    416         return retval;
    417 }
    418 
    419 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    420 {
    421         async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    422         if (exch == NULL)
    423                 return errno;
    424        
    425         ipc_call_t answer;
    426         aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
    427             handle, &answer);
    428        
    429         ipc_call_t data_request_call;
    430         aid_t data_request = async_data_read(exch, path, path_size,
    431             &data_request_call);
    432        
    433         devman_exchange_end(exch);
    434        
    435         if (data_request == 0) {
    436                 async_wait_for(req, NULL);
    437                 return ENOMEM;
    438         }
    439        
    440         sysarg_t data_request_rc;
    441         async_wait_for(data_request, &data_request_rc);
    442        
    443         sysarg_t opening_request_rc;
    444         async_wait_for(req, &opening_request_rc);
    445        
    446         if (data_request_rc != EOK) {
    447                 /* Prefer the return code of the opening request. */
    448                 if (opening_request_rc != EOK)
    449                         return (int) opening_request_rc;
    450                 else
    451                         return (int) data_request_rc;
    452         }
    453        
    454         if (opening_request_rc != EOK)
    455                 return (int) opening_request_rc;
    456        
    457         /* To be on the safe-side. */
    458         path[path_size - 1] = 0;
    459         size_t transferred_size = IPC_GET_ARG2(data_request_call);
    460         if (transferred_size >= path_size)
    461                 return ELIMIT;
    462        
    463         /* Terminate the string (trailing 0 not send over IPC). */
    464         path[transferred_size] = 0;
    465         return EOK;
    466 }
     372
     373        return retval;
     374}
     375
    467376
    468377/** @}
Note: See TracChangeset for help on using the changeset viewer.