Ignore:
File:
1 edited

Legend:

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

    rb72efe8 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.
     
    8989                        if (devman_driver_block_sess == NULL)
    9090                                devman_driver_block_sess =
    91                                     service_connect_blocking(EXCHANGE_SERIALIZE,
     91                                    service_connect_blocking(EXCHANGE_PARALLEL,
    9292                                    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    9393                }
     
    138138                if (devman_driver_sess == NULL)
    139139                        devman_driver_sess =
    140                             service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
     140                            service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN,
    141141                            DEVMAN_DRIVER, 0);
    142142               
     
    195195       
    196196        exch = devman_exchange_begin(DEVMAN_DRIVER);
    197         async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
     197        async_connect_to_me(exch, 0, 0, 0, conn, NULL);
    198198        devman_exchange_end(exch);
    199199       
     
    271271}
    272272
    273 int devman_add_device_to_class(devman_handle_t devman_handle,
    274     const char *class_name)
     273int devman_add_device_to_category(devman_handle_t devman_handle,
     274    const char *cat_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_CLASS,
     279        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY,
    280280            devman_handle, &answer);
    281         sysarg_t retval = async_data_write_start(exch, class_name,
    282             str_size(class_name));
     281        sysarg_t retval = async_data_write_start(exch, cat_name,
     282            str_size(cat_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 */
     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
    310353async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
    311354    devman_handle_t handle, unsigned int flags)
     
    323366}
    324367
    325 int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
     368int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
    326369    unsigned int flags)
    327370{
     
    333376                exch = devman_exchange_begin(DEVMAN_CLIENT);
    334377                if (exch == NULL)
    335                         return errno;
     378                        return ENOMEM;
    336379        }
    337380       
     
    364407}
    365408
    366 int devman_device_get_handle_by_class(const char *classname,
    367     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)
    368411{
    369412        async_exch_t *exch;
    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         }
     413        ipc_call_t dreply;
     414        size_t act_size;
     415        sysarg_t dretval;
     416       
     417        exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
    378418       
    379419        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);
     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) {
    387427                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        
     428                return dretval;
     429        }
     430       
     431        sysarg_t retval;
    401432        async_wait_for(req, &retval);
    402433       
    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 
    416 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)
    417457{
    418458        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    419459        if (exch == NULL)
    420                 return errno;
    421        
     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
    422485        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) {
     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) {
    433492                async_wait_for(req, NULL);
    434                 return ENOMEM;
    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;
     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);
    462504        return EOK;
    463505}
    464506
     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
    465593/** @}
    466594 */
Note: See TracChangeset for help on using the changeset viewer.