Ignore:
File:
1 edited

Legend:

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

    r7beb220 rd0dd7b5  
    11/*
    22 * Copyright (c) 2007 Josef Cejka
    3  * Copyright (c) 2011 Jiri Svoboda
     3 * Copyright (c) 2009 Jiri Svoboda
    44 * Copyright (c) 2010 Lenka Trochtova
    55 * All rights reserved.
     
    342342}
    343343
    344 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
     344int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
    345345    unsigned int flags)
    346346{
     
    383383}
    384384
    385 static 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 
    420 int 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 
    426 int 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 
    432 static 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  */
    469 static 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 
    512 int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
     385int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    513386{
    514387        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     
    516389                return ENOMEM;
    517390       
    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 
    525 int 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);
     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;
    530432}
    531433
Note: See TracChangeset for help on using the changeset viewer.