Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 7beb220 in mainline for uspace/lib/c/generic/devman.c


Ignore:
Timestamp:
2011-08-19T12:06:03Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial
Children:
2f2f1186
Parents:
d767cb1
Message:

Skeleton of devctl utility. Currently prints device tree.

File:
1 edited

Legend:

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

    rd767cb1 r7beb220  
    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.
     
    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
Note: See TracChangeset for help on using the changeset viewer.