Ignore:
File:
1 edited

Legend:

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

    r1a5b252 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.
     
    8989                        if (devman_driver_block_sess == NULL)
    9090                                devman_driver_block_sess =
    91                                     service_connect_blocking(EXCHANGE_PARALLEL,
     91                                    service_connect_blocking(EXCHANGE_SERIALIZE,
    9292                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    9393                }
     
    138138                if (devman_driver_sess == NULL)
    139139                        devman_driver_sess =
    140                             service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN,
     140                            service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
    141141                            DEVMAN_DRIVER, 0);
    142142               
     
    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 
    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 
    353310async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    354311    devman_handle_t handle, unsigned int flags)
     
    366323}
    367324
    368 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
     325int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
    369326    unsigned int flags)
    370327{
     
    376333                exch = devman_exchange_begin(DEVMAN_CLIENT);
    377334                if (exch == NULL)
    378                         return ENOMEM;
     335                        return errno;
    379336        }
    380337       
     
    407364}
    408365
    409 static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
    410     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)
    411368{
    412369        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;
     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       
    432401        async_wait_for(req, &retval);
    433402       
    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)
     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)
    457417{
    458418        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    459419        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);
    460434                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);
     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;
    504462        return EOK;
    505463}
    506464
    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 
    593465/** @}
    594466 */
Note: See TracChangeset for help on using the changeset viewer.