Ignore:
File:
1 edited

Legend:

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

    r45059d6b rb72efe8  
    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.
     
    195195       
    196196        exch = devman_exchange_begin(DEVMAN_DRIVER);
    197         async_connect_to_me(exch, 0, 0, 0, conn, NULL);
     197        async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
    198198        devman_exchange_end(exch);
    199199       
     
    271271}
    272272
    273 int devman_add_device_to_category(devman_handle_t devman_handle,
    274     const char *cat_name)
     273int devman_add_device_to_class(devman_handle_t devman_handle,
     274    const char *class_name)
    275275{
    276276        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    277277       
    278278        ipc_call_t answer;
    279         aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY,
     279        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
    280280            devman_handle, &answer);
    281         sysarg_t retval = async_data_write_start(exch, cat_name,
    282             str_size(cat_name));
     281        sysarg_t retval = async_data_write_start(exch, class_name,
     282            str_size(class_name));
    283283       
    284284        devman_exchange_end(exch);
     
    308308}
    309309
    310 /** Remove function from device.
    311  *
    312  * Request devman to remove function owned by this driver task.
    313  * @param funh      Devman handle of the function
    314  *
    315  * @return EOK on success or negative error code.
    316  */
    317 int devman_remove_function(devman_handle_t funh)
    318 {
    319         async_exch_t *exch;
    320         sysarg_t retval;
    321        
    322         exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    323         retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh);
    324         devman_exchange_end(exch);
    325        
    326         return (int) retval;
    327 }
    328 
    329310async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    330311    devman_handle_t handle, unsigned int flags)
     
    342323}
    343324
    344 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
     325int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
    345326    unsigned int flags)
    346327{
     
    352333                exch = devman_exchange_begin(DEVMAN_CLIENT);
    353334                if (exch == NULL)
    354                         return ENOMEM;
     335                        return errno;
    355336        }
    356337       
     
    383364}
    384365
    385 static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
    386     size_t buf_size)
     366int devman_device_get_handle_by_class(const char *classname,
     367    const char *devname, devman_handle_t *handle, unsigned int flags)
    387368{
    388369        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;
     370       
     371        if (flags & IPC_FLAG_BLOCKING)
     372                exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
     373        else {
     374                exch = devman_exchange_begin(DEVMAN_CLIENT);
     375                if (exch == NULL)
     376                        return errno;
     377        }
     378       
     379        ipc_call_t answer;
     380        aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     381            flags, &answer);
     382        sysarg_t retval = async_data_write_start(exch, classname,
     383            str_size(classname));
     384       
     385        if (retval != EOK) {
     386                devman_exchange_end(exch);
     387                async_wait_for(req, NULL);
     388                return retval;
     389        }
     390       
     391        retval = async_data_write_start(exch, devname,
     392            str_size(devname));
     393       
     394        devman_exchange_end(exch);
     395       
     396        if (retval != EOK) {
     397                async_wait_for(req, NULL);
     398                return retval;
     399        }
     400       
    408401        async_wait_for(req, &retval);
    409402       
    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)
     403        if (retval != EOK) {
     404                if (handle != NULL)
     405                        *handle = (devman_handle_t) -1;
     406               
     407                return retval;
     408        }
     409       
     410        if (handle != NULL)
     411                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
     412       
     413        return retval;
     414}
     415
     416int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    513417{
    514418        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    515419        if (exch == NULL)
     420                return errno;
     421       
     422        ipc_call_t answer;
     423        aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
     424            handle, &answer);
     425       
     426        ipc_call_t data_request_call;
     427        aid_t data_request = async_data_read(exch, path, path_size,
     428            &data_request_call);
     429       
     430        devman_exchange_end(exch);
     431       
     432        if (data_request == 0) {
     433                async_wait_for(req, NULL);
    516434                return ENOMEM;
    517        
    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);
    530 }
    531 
    532 int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle)
    533 {
    534         async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    535         if (exch == NULL)
    536                 return ENOMEM;
    537        
    538         sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE,
    539             sid, handle);
    540        
    541         devman_exchange_end(exch);
    542         return (int) retval;
     435        }
     436       
     437        sysarg_t data_request_rc;
     438        async_wait_for(data_request, &data_request_rc);
     439       
     440        sysarg_t opening_request_rc;
     441        async_wait_for(req, &opening_request_rc);
     442       
     443        if (data_request_rc != EOK) {
     444                /* Prefer the return code of the opening request. */
     445                if (opening_request_rc != EOK)
     446                        return (int) opening_request_rc;
     447                else
     448                        return (int) data_request_rc;
     449        }
     450       
     451        if (opening_request_rc != EOK)
     452                return (int) opening_request_rc;
     453       
     454        /* To be on the safe-side. */
     455        path[path_size - 1] = 0;
     456        size_t transferred_size = IPC_GET_ARG2(data_request_call);
     457        if (transferred_size >= path_size)
     458                return ELIMIT;
     459       
     460        /* Terminate the string (trailing 0 not send over IPC). */
     461        path[transferred_size] = 0;
     462        return EOK;
    543463}
    544464
Note: See TracChangeset for help on using the changeset viewer.