source: mainline/uspace/lib/c/generic/devman.c@ 8dab988

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8dab988 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 17.4 KB
RevLine 
[729fa2d6]1/*
2 * Copyright (c) 2007 Josef Cejka
[4c9b28a]3 * Copyright (c) 2013 Jiri Svoboda
[729fa2d6]4 * Copyright (c) 2010 Lenka Trochtova
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
[64d2b10]30
31/** @addtogroup libc
[5cd136ab]32 * @{
33 */
34/** @file
35 */
[729fa2d6]36
[b72efe8]37#include <adt/list.h>
[c47e1a8]38#include <str.h>
[729fa2d6]39#include <ipc/services.h>
[79ae36dd]40#include <ns.h>
[729fa2d6]41#include <ipc/devman.h>
42#include <devman.h>
[622dea8]43#include <fibril_synch.h>
[79ae36dd]44#include <async.h>
[729fa2d6]45#include <errno.h>
[38d150e]46#include <stdlib.h>
[729fa2d6]47
[79ae36dd]48static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex);
49static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex);
50
51static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex);
52static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex);
[729fa2d6]53
[79ae36dd]54static async_sess_t *devman_driver_block_sess = NULL;
55static async_sess_t *devman_client_block_sess = NULL;
[622dea8]56
[79ae36dd]57static async_sess_t *devman_driver_sess = NULL;
58static async_sess_t *devman_client_sess = NULL;
59
60static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
61 async_sess_t **dst)
62{
63 fibril_mutex_lock(mtx);
[a35b458]64
[79ae36dd]65 if ((*dst == NULL) && (src != NULL))
66 *dst = src;
[a35b458]67
[79ae36dd]68 fibril_mutex_unlock(mtx);
69}
70
71/** Start an async exchange on the devman session (blocking).
72 *
73 * @param iface Device manager interface to choose
74 *
75 * @return New exchange.
76 *
77 */
[f9b2cb4c]78async_exch_t *devman_exchange_begin_blocking(iface_t iface)
[729fa2d6]79{
80 switch (iface) {
[f9b2cb4c]81 case INTERFACE_DDF_DRIVER:
[79ae36dd]82 fibril_mutex_lock(&devman_driver_block_mutex);
[a35b458]83
[79ae36dd]84 while (devman_driver_block_sess == NULL) {
85 clone_session(&devman_driver_mutex, devman_driver_sess,
86 &devman_driver_block_sess);
[a35b458]87
[79ae36dd]88 if (devman_driver_block_sess == NULL)
89 devman_driver_block_sess =
[f9b2cb4c]90 service_connect_blocking(SERVICE_DEVMAN,
91 INTERFACE_DDF_DRIVER, 0);
[622dea8]92 }
[a35b458]93
[79ae36dd]94 fibril_mutex_unlock(&devman_driver_block_mutex);
[a35b458]95
[79ae36dd]96 clone_session(&devman_driver_mutex, devman_driver_block_sess,
97 &devman_driver_sess);
[a35b458]98
[79ae36dd]99 return async_exchange_begin(devman_driver_block_sess);
[f9b2cb4c]100 case INTERFACE_DDF_CLIENT:
[79ae36dd]101 fibril_mutex_lock(&devman_client_block_mutex);
[a35b458]102
[79ae36dd]103 while (devman_client_block_sess == NULL) {
104 clone_session(&devman_client_mutex, devman_client_sess,
105 &devman_client_block_sess);
[a35b458]106
[79ae36dd]107 if (devman_client_block_sess == NULL)
108 devman_client_block_sess =
[f9b2cb4c]109 service_connect_blocking(SERVICE_DEVMAN,
110 INTERFACE_DDF_CLIENT, 0);
[4db43721]111 }
[a35b458]112
[79ae36dd]113 fibril_mutex_unlock(&devman_client_block_mutex);
[a35b458]114
[79ae36dd]115 clone_session(&devman_client_mutex, devman_client_block_sess,
116 &devman_client_sess);
[a35b458]117
[79ae36dd]118 return async_exchange_begin(devman_client_block_sess);
[729fa2d6]119 default:
[79ae36dd]120 return NULL;
[729fa2d6]121 }
122}
123
[79ae36dd]124/** Start an async exchange on the devman session.
125 *
126 * @param iface Device manager interface to choose
127 *
128 * @return New exchange.
129 *
130 */
[f9b2cb4c]131async_exch_t *devman_exchange_begin(iface_t iface)
[79ae36dd]132{
133 switch (iface) {
[f9b2cb4c]134 case INTERFACE_DDF_DRIVER:
[79ae36dd]135 fibril_mutex_lock(&devman_driver_mutex);
[a35b458]136
[79ae36dd]137 if (devman_driver_sess == NULL)
138 devman_driver_sess =
[f9b2cb4c]139 service_connect(SERVICE_DEVMAN,
140 INTERFACE_DDF_DRIVER, 0);
[a35b458]141
[79ae36dd]142 fibril_mutex_unlock(&devman_driver_mutex);
[a35b458]143
[79ae36dd]144 if (devman_driver_sess == NULL)
145 return NULL;
[a35b458]146
[79ae36dd]147 return async_exchange_begin(devman_driver_sess);
[f9b2cb4c]148 case INTERFACE_DDF_CLIENT:
[79ae36dd]149 fibril_mutex_lock(&devman_client_mutex);
[a35b458]150
[79ae36dd]151 if (devman_client_sess == NULL)
152 devman_client_sess =
[f9b2cb4c]153 service_connect(SERVICE_DEVMAN,
154 INTERFACE_DDF_CLIENT, 0);
[a35b458]155
[79ae36dd]156 fibril_mutex_unlock(&devman_client_mutex);
[a35b458]157
[79ae36dd]158 if (devman_client_sess == NULL)
159 return NULL;
[a35b458]160
[79ae36dd]161 return async_exchange_begin(devman_client_sess);
162 default:
163 return NULL;
164 }
165}
166
167/** Finish an async exchange on the devman session.
168 *
169 * @param exch Exchange to be finished.
170 *
171 */
172void devman_exchange_end(async_exch_t *exch)
173{
174 async_exchange_end(exch);
175}
176
[729fa2d6]177/** Register running driver with device manager. */
[b7fd2a0]178errno_t devman_driver_register(const char *name)
[729fa2d6]179{
[f9b2cb4c]180 async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
[a35b458]181
[729fa2d6]182 ipc_call_t answer;
[79ae36dd]183 aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
[b7fd2a0]184 errno_t retval = async_data_write_start(exch, name, str_size(name));
[a35b458]185
[79ae36dd]186 devman_exchange_end(exch);
[a35b458]187
[729fa2d6]188 if (retval != EOK) {
[50b581d]189 async_forget(req);
[79ae36dd]190 return retval;
[729fa2d6]191 }
[a35b458]192
[f9b2cb4c]193 exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
194 async_connect_to_me(exch, 0, 0, 0);
[79ae36dd]195 devman_exchange_end(exch);
[a35b458]196
[79ae36dd]197 async_wait_for(req, &retval);
[729fa2d6]198 return retval;
199}
200
[8b1e15ac]201/** Add function to a device.
202 *
203 * Request devman to add a new function to the specified device owned by
204 * this driver task.
205 *
[79ae36dd]206 * @param name Name of the new function
207 * @param ftype Function type, fun_inner or fun_exposed
208 * @param match_ids Match IDs (should be empty for fun_exposed)
209 * @param devh Devman handle of the device
210 * @param funh Place to store handle of the new function
211 *
[cde999a]212 * @return EOK on success or an error code.
[8b1e15ac]213 *
214 */
[b7fd2a0]215errno_t devman_add_function(const char *name, fun_type_t ftype,
[8b1e15ac]216 match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
[1b367b4]217{
[be12474]218 unsigned long match_count = list_count(&match_ids->ids);
[f9b2cb4c]219 async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
[a35b458]220
[7707954]221 ipc_call_t answer;
[79ae36dd]222 aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
[8b1e15ac]223 devh, match_count, &answer);
[b7fd2a0]224 errno_t retval = async_data_write_start(exch, name, str_size(name));
[7707954]225 if (retval != EOK) {
[79ae36dd]226 devman_exchange_end(exch);
[50b581d]227 async_forget(req);
[7707954]228 return retval;
229 }
[a35b458]230
[feeac0d]231 list_foreach(match_ids->ids, link, match_id_t, match_id) {
[15e54f5]232 ipc_call_t answer2;
233 aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
234 match_id->score, &answer2);
[79ae36dd]235 retval = async_data_write_start(exch, match_id->id,
236 str_size(match_id->id));
237 if (retval != EOK) {
238 devman_exchange_end(exch);
[50b581d]239 async_forget(req2);
240 async_forget(req);
[79ae36dd]241 return retval;
242 }
[a35b458]243
[15e54f5]244 async_wait_for(req2, &retval);
[79ae36dd]245 if (retval != EOK) {
246 devman_exchange_end(exch);
[50b581d]247 async_forget(req);
[79ae36dd]248 return retval;
249 }
[4265fd4]250 }
[a35b458]251
[79ae36dd]252 devman_exchange_end(exch);
[a35b458]253
[15e54f5]254 async_wait_for(req, &retval);
[e6211f8]255 if (retval == EOK) {
[15e54f5]256 if (funh != NULL)
257 *funh = (int) IPC_GET_ARG1(answer);
258 } else {
259 if (funh != NULL)
260 *funh = -1;
261 }
[a35b458]262
[15e54f5]263 return retval;
[7707954]264}
265
[b7fd2a0]266errno_t devman_add_device_to_category(devman_handle_t devman_handle,
[1dc4a5e]267 const char *cat_name)
[692c40cb]268{
[f9b2cb4c]269 async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
[a35b458]270
[692c40cb]271 ipc_call_t answer;
[1dc4a5e]272 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY,
[1b367b4]273 devman_handle, &answer);
[b7fd2a0]274 errno_t retval = async_data_write_start(exch, cat_name,
[1dc4a5e]275 str_size(cat_name));
[a35b458]276
[79ae36dd]277 devman_exchange_end(exch);
[a35b458]278
[692c40cb]279 if (retval != EOK) {
[50b581d]280 async_forget(req);
[692c40cb]281 return retval;
282 }
[a35b458]283
[692c40cb]284 async_wait_for(req, &retval);
[1b367b4]285 return retval;
[692c40cb]286}
287
[f9b2cb4c]288async_sess_t *devman_device_connect(devman_handle_t handle, unsigned int flags)
[5cd136ab]289{
[79ae36dd]290 async_sess_t *sess;
[a35b458]291
[79ae36dd]292 if (flags & IPC_FLAG_BLOCKING)
[f9b2cb4c]293 sess = service_connect_blocking(SERVICE_DEVMAN,
294 INTERFACE_DEVMAN_DEVICE, handle);
[79ae36dd]295 else
[f9b2cb4c]296 sess = service_connect(SERVICE_DEVMAN,
297 INTERFACE_DEVMAN_DEVICE, handle);
[a35b458]298
[79ae36dd]299 return sess;
[5cd136ab]300}
301
[d0dd7b5]302/** Remove function from device.
303 *
304 * Request devman to remove function owned by this driver task.
305 * @param funh Devman handle of the function
306 *
[cde999a]307 * @return EOK on success or an error code.
[d0dd7b5]308 */
[b7fd2a0]309errno_t devman_remove_function(devman_handle_t funh)
[d0dd7b5]310{
311 async_exch_t *exch;
[b7fd2a0]312 errno_t retval;
[a35b458]313
[f9b2cb4c]314 exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
[d0dd7b5]315 retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh);
316 devman_exchange_end(exch);
[a35b458]317
[25a179e]318 return retval;
[d0dd7b5]319}
320
[b7fd2a0]321errno_t devman_drv_fun_online(devman_handle_t funh)
[1a5b252]322{
[f9b2cb4c]323 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
[1a5b252]324 if (exch == NULL)
325 return ENOMEM;
[a35b458]326
[b7fd2a0]327 errno_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh);
[a35b458]328
[1a5b252]329 devman_exchange_end(exch);
[25a179e]330 return retval;
[1a5b252]331}
332
[b7fd2a0]333errno_t devman_drv_fun_offline(devman_handle_t funh)
[1a5b252]334{
[f9b2cb4c]335 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
[1a5b252]336 if (exch == NULL)
337 return ENOMEM;
[a35b458]338
[b7fd2a0]339 errno_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh);
[a35b458]340
[1a5b252]341 devman_exchange_end(exch);
[25a179e]342 return retval;
[1a5b252]343}
344
[f9b2cb4c]345async_sess_t *devman_parent_device_connect(devman_handle_t handle,
346 unsigned int flags)
[5cd136ab]347{
[79ae36dd]348 async_sess_t *sess;
[a35b458]349
[79ae36dd]350 if (flags & IPC_FLAG_BLOCKING)
[f9b2cb4c]351 sess = service_connect_blocking(SERVICE_DEVMAN,
352 INTERFACE_DEVMAN_PARENT, handle);
[79ae36dd]353 else
[f9b2cb4c]354 sess = service_connect_blocking(SERVICE_DEVMAN,
355 INTERFACE_DEVMAN_PARENT, handle);
[a35b458]356
[79ae36dd]357 return sess;
[5cd136ab]358}
359
[b7fd2a0]360errno_t devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
[1b367b4]361 unsigned int flags)
[f658458]362{
[79ae36dd]363 async_exch_t *exch;
[a35b458]364
[79ae36dd]365 if (flags & IPC_FLAG_BLOCKING)
[f9b2cb4c]366 exch = devman_exchange_begin_blocking(INTERFACE_DDF_CLIENT);
[79ae36dd]367 else {
[f9b2cb4c]368 exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[79ae36dd]369 if (exch == NULL)
[e280857]370 return ENOMEM;
[79ae36dd]371 }
[a35b458]372
[f658458]373 ipc_call_t answer;
[79ae36dd]374 aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
[f658458]375 &answer);
[b7fd2a0]376 errno_t retval = async_data_write_start(exch, pathname,
[1b367b4]377 str_size(pathname));
[a35b458]378
[79ae36dd]379 devman_exchange_end(exch);
[a35b458]380
[f658458]381 if (retval != EOK) {
[50b581d]382 async_forget(req);
[f658458]383 return retval;
384 }
[a35b458]385
[f658458]386 async_wait_for(req, &retval);
[a35b458]387
[f658458]388 if (retval != EOK) {
389 if (handle != NULL)
[0b5a4131]390 *handle = (devman_handle_t) -1;
[a35b458]391
[f658458]392 return retval;
393 }
[a35b458]394
[f658458]395 if (handle != NULL)
[0b5a4131]396 *handle = (devman_handle_t) IPC_GET_ARG1(answer);
[a35b458]397
[f658458]398 return retval;
399}
400
[b7fd2a0]401static errno_t devman_get_str_internal(sysarg_t method, sysarg_t arg1,
[4c9b28a]402 sysarg_t arg2, sysarg_t *r1, char *buf, size_t buf_size)
[431d6d6]403{
[7beb220]404 async_exch_t *exch;
405 ipc_call_t dreply;
406 size_t act_size;
[b7fd2a0]407 errno_t dretval;
[a35b458]408
[f9b2cb4c]409 exch = devman_exchange_begin_blocking(INTERFACE_DDF_CLIENT);
[a35b458]410
[7beb220]411 ipc_call_t answer;
[4c9b28a]412 aid_t req = async_send_2(exch, method, arg1, arg2, &answer);
[7beb220]413 aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply);
414 async_wait_for(dreq, &dretval);
[a35b458]415
[79ae36dd]416 devman_exchange_end(exch);
[a35b458]417
[7beb220]418 if (dretval != EOK) {
[50b581d]419 async_forget(req);
[7beb220]420 return dretval;
[431d6d6]421 }
[a35b458]422
[b7fd2a0]423 errno_t retval;
[7beb220]424 async_wait_for(req, &retval);
[a35b458]425
[3f57fb7]426 if (retval != EOK) {
[7beb220]427 return retval;
[3f57fb7]428 }
[a35b458]429
[4c9b28a]430 if (r1 != NULL)
431 *r1 = IPC_GET_ARG1(answer);
[7beb220]432 act_size = IPC_GET_ARG2(dreply);
433 assert(act_size <= buf_size - 1);
434 buf[act_size] = '\0';
[a35b458]435
[7beb220]436 return EOK;
437}
438
[b7fd2a0]439errno_t devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size)
[7beb220]440{
[4c9b28a]441 return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, 0, NULL,
442 buf, buf_size);
443}
444
[b7fd2a0]445errno_t devman_fun_get_match_id(devman_handle_t handle, size_t index, char *buf,
[4c9b28a]446 size_t buf_size, unsigned int *rscore)
447{
[b7fd2a0]448 errno_t rc;
[4c9b28a]449 sysarg_t score = 0;
450
451 rc = devman_get_str_internal(DEVMAN_FUN_GET_MATCH_ID, handle, index,
452 &score, buf, buf_size);
453 if (rc != EOK)
454 return rc;
455
456 *rscore = score;
457 return rc;
[7beb220]458}
459
[b7fd2a0]460errno_t devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size)
[7beb220]461{
[4c9b28a]462 return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, 0, NULL,
463 buf, buf_size);
[7beb220]464}
465
[b7fd2a0]466errno_t devman_fun_get_driver_name(devman_handle_t handle, char *buf, size_t buf_size)
[3f57fb7]467{
[4c9b28a]468 return devman_get_str_internal(DEVMAN_FUN_GET_DRIVER_NAME, handle, 0,
469 NULL, buf, buf_size);
[3f57fb7]470}
471
[b7fd2a0]472errno_t devman_fun_online(devman_handle_t funh)
[1a5b252]473{
[f9b2cb4c]474 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[1a5b252]475 if (exch == NULL)
476 return ENOMEM;
[a35b458]477
[b7fd2a0]478 errno_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh);
[a35b458]479
[1a5b252]480 devman_exchange_end(exch);
[25a179e]481 return retval;
[1a5b252]482}
483
[b7fd2a0]484errno_t devman_fun_offline(devman_handle_t funh)
[1a5b252]485{
[f9b2cb4c]486 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[1a5b252]487 if (exch == NULL)
488 return ENOMEM;
[a35b458]489
[b7fd2a0]490 errno_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh);
[a35b458]491
[1a5b252]492 devman_exchange_end(exch);
[25a179e]493 return retval;
[1a5b252]494}
495
[b7fd2a0]496static errno_t devman_get_handles_once(sysarg_t method, sysarg_t arg1,
[7beb220]497 devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
498{
[f9b2cb4c]499 async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_CLIENT);
[7beb220]500
501 ipc_call_t answer;
502 aid_t req = async_send_1(exch, method, arg1, &answer);
[b7fd2a0]503 errno_t rc = async_data_read_start(exch, handle_buf, buf_size);
[a35b458]504
[7beb220]505 devman_exchange_end(exch);
[a35b458]506
[7beb220]507 if (rc != EOK) {
[50b581d]508 async_forget(req);
[7beb220]509 return rc;
[431d6d6]510 }
[a35b458]511
[b7fd2a0]512 errno_t retval;
[7beb220]513 async_wait_for(req, &retval);
[a35b458]514
[7beb220]515 if (retval != EOK) {
516 return retval;
517 }
[a35b458]518
[7beb220]519 *act_size = IPC_GET_ARG1(answer);
[431d6d6]520 return EOK;
521}
522
[7beb220]523/** Get list of handles.
524 *
525 * Returns an allocated array of handles.
526 *
527 * @param method IPC method
528 * @param arg1 IPC argument 1
529 * @param data Place to store pointer to array of handles
530 * @param count Place to store number of handles
[cde999a]531 * @return EOK on success or an error code
[7beb220]532 */
[b7fd2a0]533static errno_t devman_get_handles_internal(sysarg_t method, sysarg_t arg1,
[7beb220]534 devman_handle_t **data, size_t *count)
535{
536 devman_handle_t *handles;
537 size_t act_size;
538 size_t alloc_size;
[b7fd2a0]539 errno_t rc;
[7beb220]540
541 *data = NULL;
542 act_size = 0; /* silence warning */
543
544 rc = devman_get_handles_once(method, arg1, NULL, 0,
545 &act_size);
546 if (rc != EOK)
547 return rc;
548
549 alloc_size = act_size;
550 handles = malloc(alloc_size);
551 if (handles == NULL)
552 return ENOMEM;
553
554 while (true) {
555 rc = devman_get_handles_once(method, arg1, handles, alloc_size,
556 &act_size);
557 if (rc != EOK)
558 return rc;
559
560 if (act_size <= alloc_size)
561 break;
562
563 alloc_size *= 2;
564 free(handles);
565
566 handles = malloc(alloc_size);
567 if (handles == NULL)
568 return ENOMEM;
569 }
570
571 *count = act_size / sizeof(devman_handle_t);
572 *data = handles;
573 return EOK;
574}
575
[b7fd2a0]576errno_t devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
[7beb220]577{
[f9b2cb4c]578 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[7beb220]579 if (exch == NULL)
580 return ENOMEM;
[a35b458]581
[b7fd2a0]582 errno_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD,
[7beb220]583 funh, devh);
[a35b458]584
[7beb220]585 devman_exchange_end(exch);
[25a179e]586 return retval;
[7beb220]587}
588
[b7fd2a0]589errno_t devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs,
[7beb220]590 size_t *count)
591{
592 return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS,
593 devh, funcs, count);
594}
595
[b7fd2a0]596errno_t devman_dev_get_parent(devman_handle_t devh, devman_handle_t *funh)
[1db5669]597{
[f9b2cb4c]598 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[1db5669]599 if (exch == NULL)
600 return ENOMEM;
[a35b458]601
[b7fd2a0]602 errno_t retval = async_req_1_1(exch, DEVMAN_DEV_GET_PARENT,
[1db5669]603 devh, funh);
[a35b458]604
[1db5669]605 devman_exchange_end(exch);
[25a179e]606 return retval;
[1db5669]607}
608
[b7fd2a0]609errno_t devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle)
[e280857]610{
[f9b2cb4c]611 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[e280857]612 if (exch == NULL)
613 return ENOMEM;
[a35b458]614
[b7fd2a0]615 errno_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE,
[e280857]616 sid, handle);
[a35b458]617
[e280857]618 devman_exchange_end(exch);
[25a179e]619 return retval;
[e280857]620}
621
[b7fd2a0]622errno_t devman_get_drivers(devman_handle_t **drvs,
[0511549]623 size_t *count)
624{
625 return devman_get_handles_internal(DEVMAN_GET_DRIVERS, 0, drvs, count);
626}
627
[b7fd2a0]628errno_t devman_driver_get_devices(devman_handle_t drvh, devman_handle_t **devs,
[1db5669]629 size_t *count)
630{
631 return devman_get_handles_internal(DEVMAN_DRIVER_GET_DEVICES,
632 drvh, devs, count);
633}
634
[b7fd2a0]635errno_t devman_driver_get_handle(const char *drvname, devman_handle_t *handle)
[7969087]636{
637 async_exch_t *exch;
638
[f9b2cb4c]639 exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[7969087]640 if (exch == NULL)
641 return ENOMEM;
[a35b458]642
[7969087]643 ipc_call_t answer;
644 aid_t req = async_send_0(exch, DEVMAN_DRIVER_GET_HANDLE, &answer);
[b7fd2a0]645 errno_t retval = async_data_write_start(exch, drvname,
[7969087]646 str_size(drvname));
[a35b458]647
[7969087]648 devman_exchange_end(exch);
[a35b458]649
[7969087]650 if (retval != EOK) {
651 async_forget(req);
652 return retval;
653 }
[a35b458]654
[7969087]655 async_wait_for(req, &retval);
[a35b458]656
[7969087]657 if (retval != EOK) {
658 if (handle != NULL)
659 *handle = (devman_handle_t) -1;
[a35b458]660
[7969087]661 return retval;
662 }
[a35b458]663
[7969087]664 if (handle != NULL)
665 *handle = (devman_handle_t) IPC_GET_ARG1(answer);
[a35b458]666
[7969087]667 return retval;
668}
669
[b7fd2a0]670errno_t devman_driver_get_match_id(devman_handle_t handle, size_t index, char *buf,
[4c9b28a]671 size_t buf_size, unsigned int *rscore)
672{
[b7fd2a0]673 errno_t rc;
[4c9b28a]674 sysarg_t score = 0;
675
676 rc = devman_get_str_internal(DEVMAN_DRIVER_GET_MATCH_ID, handle, index,
677 &score, buf, buf_size);
678 if (rc != EOK)
679 return rc;
680
681 *rscore = score;
682 return rc;
683}
684
[b7fd2a0]685errno_t devman_driver_get_name(devman_handle_t handle, char *buf, size_t buf_size)
[0511549]686{
[4c9b28a]687 return devman_get_str_internal(DEVMAN_DRIVER_GET_NAME, handle, 0, NULL,
688 buf, buf_size);
[0511549]689}
690
[b7fd2a0]691errno_t devman_driver_get_state(devman_handle_t drvh, driver_state_t *rstate)
[e5556e4a]692{
693 sysarg_t state;
[f9b2cb4c]694 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[e5556e4a]695 if (exch == NULL)
696 return ENOMEM;
[a35b458]697
[b7fd2a0]698 errno_t rc = async_req_1_1(exch, DEVMAN_DRIVER_GET_STATE, drvh,
[e5556e4a]699 &state);
[a35b458]700
[e5556e4a]701 devman_exchange_end(exch);
702 if (rc != EOK)
703 return rc;
704
705 *rstate = state;
706 return rc;
707}
708
[b7fd2a0]709errno_t devman_driver_load(devman_handle_t drvh)
[7969087]710{
[f9b2cb4c]711 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
[7969087]712 if (exch == NULL)
713 return ENOMEM;
[a35b458]714
[b7fd2a0]715 errno_t rc = async_req_1_0(exch, DEVMAN_DRIVER_LOAD, drvh);
[a35b458]716
[7969087]717 devman_exchange_end(exch);
718 return rc;
719}
720
[b7fd2a0]721errno_t devman_driver_unload(devman_handle_t drvh)
[81685dd9]722{
723 async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
724 if (exch == NULL)
725 return ENOMEM;
[a35b458]726
[b7fd2a0]727 errno_t rc = async_req_1_0(exch, DEVMAN_DRIVER_UNLOAD, drvh);
[a35b458]728
[81685dd9]729 devman_exchange_end(exch);
730 return rc;
731}
732
[5cd136ab]733/** @}
[398c4d7]734 */
Note: See TracBrowser for help on using the repository browser.