Ignore:
File:
1 edited

Legend:

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

    r1a5b252 re6211f8  
    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.
     
    3535 */
    3636
    37 #include <adt/list.h>
    3837#include <str.h>
    3938#include <ipc/services.h>
     
    8988                        if (devman_driver_block_sess == NULL)
    9089                                devman_driver_block_sess =
    91                                     service_connect_blocking(EXCHANGE_PARALLEL,
     90                                    service_connect_blocking(EXCHANGE_SERIALIZE,
    9291                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    9392                }
     
    138137                if (devman_driver_sess == NULL)
    139138                        devman_driver_sess =
    140                             service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN,
     139                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
    141140                            DEVMAN_DRIVER, 0);
    142141               
     
    195194       
    196195        exch = devman_exchange_begin(DEVMAN_DRIVER);
    197         async_connect_to_me(exch, 0, 0, 0, conn, NULL);
     196        async_connect_to_me(exch, 0, 0, 0, NULL);
    198197        devman_exchange_end(exch);
    199198       
     
    232231        }
    233232       
     233        link_t *link = match_ids->ids.next;
    234234        match_id_t *match_id = NULL;
    235235       
    236         list_foreach(match_ids->ids, link) {
     236        while (link != &match_ids->ids) {
    237237                match_id = list_get_instance(link, match_id_t, link);
    238238               
     
    255255                        return retval;
    256256                }
     257               
     258                link = link->next;
    257259        }
    258260       
     
    271273}
    272274
    273 int devman_add_device_to_category(devman_handle_t devman_handle,
    274     const char *cat_name)
     275int devman_add_device_to_class(devman_handle_t devman_handle,
     276    const char *class_name)
    275277{
    276278        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    277279       
    278280        ipc_call_t answer;
    279         aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY,
     281        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
    280282            devman_handle, &answer);
    281         sysarg_t retval = async_data_write_start(exch, cat_name,
    282             str_size(cat_name));
     283        sysarg_t retval = async_data_write_start(exch, class_name,
     284            str_size(class_name));
    283285       
    284286        devman_exchange_end(exch);
     
    308310}
    309311
    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 
    329 int devman_drv_fun_online(devman_handle_t funh)
    330 {
    331         async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
    332         if (exch == NULL)
    333                 return ENOMEM;
    334        
    335         sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh);
    336        
    337         devman_exchange_end(exch);
    338         return (int) retval;
    339 }
    340 
    341 int devman_drv_fun_offline(devman_handle_t funh)
    342 {
    343         async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER);
    344         if (exch == NULL)
    345                 return ENOMEM;
    346        
    347         sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh);
    348        
    349         devman_exchange_end(exch);
    350         return (int) retval;
    351 }
    352 
    353312async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    354313    devman_handle_t handle, unsigned int flags)
     
    366325}
    367326
    368 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
     327int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
    369328    unsigned int flags)
    370329{
     
    376335                exch = devman_exchange_begin(DEVMAN_CLIENT);
    377336                if (exch == NULL)
    378                         return ENOMEM;
     337                        return errno;
    379338        }
    380339       
     
    407366}
    408367
    409 static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
    410     size_t buf_size)
     368int devman_device_get_handle_by_class(const char *classname,
     369    const char *devname, devman_handle_t *handle, unsigned int flags)
    411370{
    412371        async_exch_t *exch;
    413         ipc_call_t dreply;
    414         size_t act_size;
    415         sysarg_t dretval;
    416        
    417         exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
    418        
    419         ipc_call_t answer;
    420         aid_t req = async_send_1(exch, method, arg1, &answer);
    421         aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply);
    422         async_wait_for(dreq, &dretval);
    423        
    424         devman_exchange_end(exch);
    425        
    426         if (dretval != EOK) {
    427                 async_wait_for(req, NULL);
    428                 return dretval;
    429         }
    430        
    431         sysarg_t retval;
     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,
     383            flags, &answer);
     384        sysarg_t retval = async_data_write_start(exch, classname,
     385            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,
     394            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       
    432403        async_wait_for(req, &retval);
    433404       
    434         if (retval != EOK)
    435                 return retval;
    436        
    437         act_size = IPC_GET_ARG2(dreply);
    438         assert(act_size <= buf_size - 1);
    439         buf[act_size] = '\0';
    440        
    441         return EOK;
    442 }
    443 
    444 int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size)
    445 {
    446         return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf,
    447             buf_size);
    448 }
    449 
    450 int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size)
    451 {
    452         return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf,
    453             buf_size);
    454 }
    455 
    456 int devman_fun_online(devman_handle_t funh)
     405        if (retval != EOK) {
     406                if (handle != NULL)
     407                        *handle = (devman_handle_t) -1;
     408               
     409                return retval;
     410        }
     411       
     412        if (handle != NULL)
     413                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
     414       
     415        return retval;
     416}
     417
     418int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    457419{
    458420        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    459421        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);
    460436                return ENOMEM;
    461        
    462         sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh);
    463        
    464         devman_exchange_end(exch);
    465         return (int) retval;
    466 }
    467 
    468 int devman_fun_offline(devman_handle_t funh)
    469 {
    470         async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    471         if (exch == NULL)
    472                 return ENOMEM;
    473        
    474         sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh);
    475        
    476         devman_exchange_end(exch);
    477         return (int) retval;
    478 }
    479 
    480 static int devman_get_handles_once(sysarg_t method, sysarg_t arg1,
    481     devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
    482 {
    483         async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
    484 
    485         ipc_call_t answer;
    486         aid_t req = async_send_1(exch, method, arg1, &answer);
    487         int rc = async_data_read_start(exch, handle_buf, buf_size);
    488        
    489         devman_exchange_end(exch);
    490        
    491         if (rc != EOK) {
    492                 async_wait_for(req, NULL);
    493                 return rc;
    494         }
    495        
    496         sysarg_t retval;
    497         async_wait_for(req, &retval);
    498        
    499         if (retval != EOK) {
    500                 return retval;
    501         }
    502        
    503         *act_size = IPC_GET_ARG1(answer);
     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;
    504464        return EOK;
    505465}
    506466
    507 /** Get list of handles.
    508  *
    509  * Returns an allocated array of handles.
    510  *
    511  * @param method        IPC method
    512  * @param arg1          IPC argument 1
    513  * @param data          Place to store pointer to array of handles
    514  * @param count         Place to store number of handles
    515  * @return              EOK on success or negative error code
    516  */
    517 static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1,
    518     devman_handle_t **data, size_t *count)
    519 {
    520         devman_handle_t *handles;
    521         size_t act_size;
    522         size_t alloc_size;
    523         int rc;
    524 
    525         *data = NULL;
    526         act_size = 0;   /* silence warning */
    527 
    528         rc = devman_get_handles_once(method, arg1, NULL, 0,
    529             &act_size);
    530         if (rc != EOK)
    531                 return rc;
    532 
    533         alloc_size = act_size;
    534         handles = malloc(alloc_size);
    535         if (handles == NULL)
    536                 return ENOMEM;
    537 
    538         while (true) {
    539                 rc = devman_get_handles_once(method, arg1, handles, alloc_size,
    540                     &act_size);
    541                 if (rc != EOK)
    542                         return rc;
    543 
    544                 if (act_size <= alloc_size)
    545                         break;
    546 
    547                 alloc_size *= 2;
    548                 free(handles);
    549 
    550                 handles = malloc(alloc_size);
    551                 if (handles == NULL)
    552                         return ENOMEM;
    553         }
    554 
    555         *count = act_size / sizeof(devman_handle_t);
    556         *data = handles;
    557         return EOK;
    558 }
    559 
    560 int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
    561 {
    562         async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    563         if (exch == NULL)
    564                 return ENOMEM;
    565        
    566         sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD,
    567             funh, devh);
    568        
    569         devman_exchange_end(exch);
    570         return (int) retval;
    571 }
    572 
    573 int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs,
    574     size_t *count)
    575 {
    576         return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS,
    577             devh, funcs, count);
    578 }
    579 
    580 int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle)
    581 {
    582         async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    583         if (exch == NULL)
    584                 return ENOMEM;
    585        
    586         sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE,
    587             sid, handle);
    588        
    589         devman_exchange_end(exch);
    590         return (int) retval;
    591 }
    592 
    593467/** @}
    594468 */
Note: See TracChangeset for help on using the changeset viewer.