Ignore:
File:
1 edited

Legend:

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

    re6211f8 r1a5b252  
    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.
     
    3535 */
    3636
     37#include <adt/list.h>
    3738#include <str.h>
    3839#include <ipc/services.h>
     
    8889                        if (devman_driver_block_sess == NULL)
    8990                                devman_driver_block_sess =
    90                                     service_connect_blocking(EXCHANGE_SERIALIZE,
     91                                    service_connect_blocking(EXCHANGE_PARALLEL,
    9192                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    9293                }
     
    137138                if (devman_driver_sess == NULL)
    138139                        devman_driver_sess =
    139                             service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     140                            service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN,
    140141                            DEVMAN_DRIVER, 0);
    141142               
     
    194195       
    195196        exch = devman_exchange_begin(DEVMAN_DRIVER);
    196         async_connect_to_me(exch, 0, 0, 0, NULL);
     197        async_connect_to_me(exch, 0, 0, 0, conn, NULL);
    197198        devman_exchange_end(exch);
    198199       
     
    231232        }
    232233       
    233         link_t *link = match_ids->ids.next;
    234234        match_id_t *match_id = NULL;
    235235       
    236         while (link != &match_ids->ids) {
     236        list_foreach(match_ids->ids, link) {
    237237                match_id = list_get_instance(link, match_id_t, link);
    238238               
     
    255255                        return retval;
    256256                }
    257                
    258                 link = link->next;
    259257        }
    260258       
     
    273271}
    274272
    275 int devman_add_device_to_class(devman_handle_t devman_handle,
    276     const char *class_name)
     273int devman_add_device_to_category(devman_handle_t devman_handle,
     274    const char *cat_name)
    277275{
    278276        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    279277       
    280278        ipc_call_t answer;
    281         aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
     279        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY,
    282280            devman_handle, &answer);
    283         sysarg_t retval = async_data_write_start(exch, class_name,
    284             str_size(class_name));
     281        sysarg_t retval = async_data_write_start(exch, cat_name,
     282            str_size(cat_name));
    285283       
    286284        devman_exchange_end(exch);
     
    310308}
    311309
     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 */
     317int 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
     329int 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
     341int 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
    312353async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    313354    devman_handle_t handle, unsigned int flags)
     
    325366}
    326367
    327 int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
     368int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
    328369    unsigned int flags)
    329370{
     
    335376                exch = devman_exchange_begin(DEVMAN_CLIENT);
    336377                if (exch == NULL)
    337                         return errno;
     378                        return ENOMEM;
    338379        }
    339380       
     
    366407}
    367408
    368 int devman_device_get_handle_by_class(const char *classname,
    369     const char *devname, devman_handle_t *handle, unsigned int flags)
     409static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
     410    size_t buf_size)
    370411{
    371412        async_exch_t *exch;
    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         }
     413        ipc_call_t dreply;
     414        size_t act_size;
     415        sysarg_t dretval;
     416       
     417        exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
    380418       
    381419        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);
     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) {
    389427                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        
     428                return dretval;
     429        }
     430       
     431        sysarg_t retval;
    403432        async_wait_for(req, &retval);
    404433       
    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 
    418 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
     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
     444int 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
     450int 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
     456int devman_fun_online(devman_handle_t funh)
    419457{
    420458        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    421459        if (exch == NULL)
    422                 return errno;
    423        
     460                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
     468int 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
     480static 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
    424485        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) {
     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) {
    435492                async_wait_for(req, NULL);
    436                 return ENOMEM;
    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;
     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);
    464504        return EOK;
    465505}
    466506
     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 */
     517static 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
     560int 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
     573int 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
     580int 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
    467593/** @}
    468594 */
Note: See TracChangeset for help on using the changeset viewer.