source: mainline/uspace/srv/devman/client_conn.c@ 25a179e

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

IPC return values are always errno constants. Adjust types to reflect that.

In principle, IPC server is not allowed to return non-errno values via
the "main" return value, because kernel interprets it (e.g. EHANGUP).
It's still possible to return arbitrary additional return values alongside EOK,
which are not interpreted in normal communication.

  • Property mode set to 100644
File size: 19.1 KB
Line 
1/*
2 * Copyright (c) 2010 Lenka Trochtova
3 * Copyright (c) 2013 Jiri Svoboda
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/**
31 * @defgroup devman Device manager.
32 * @brief HelenOS device manager.
33 * @{
34 */
35
36/** @file
37 */
38
39#include <inttypes.h>
40#include <assert.h>
41#include <ns.h>
42#include <async.h>
43#include <stdio.h>
44#include <errno.h>
45#include <str_error.h>
46#include <stdbool.h>
47#include <fibril_synch.h>
48#include <stdlib.h>
49#include <str.h>
50#include <ctype.h>
51#include <ipc/devman.h>
52
53#include "client_conn.h"
54#include "dev.h"
55#include "devman.h"
56#include "driver.h"
57#include "fun.h"
58#include "loc.h"
59#include "main.h"
60
61/** Find handle for the device instance identified by the device's path in the
62 * device tree. */
63static void devman_function_get_handle(ipc_callid_t iid, ipc_call_t *icall)
64{
65 char *pathname;
66 devman_handle_t handle;
67
68 int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0);
69 if (rc != EOK) {
70 async_answer_0(iid, rc);
71 return;
72 }
73
74 fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname);
75
76 free(pathname);
77
78 if (fun == NULL) {
79 async_answer_0(iid, ENOENT);
80 return;
81 }
82
83 fibril_rwlock_read_lock(&device_tree.rwlock);
84
85 /* Check function state */
86 if (fun->state == FUN_REMOVED) {
87 fibril_rwlock_read_unlock(&device_tree.rwlock);
88 async_answer_0(iid, ENOENT);
89 return;
90 }
91 handle = fun->handle;
92
93 fibril_rwlock_read_unlock(&device_tree.rwlock);
94
95 /* Delete reference created above by find_fun_node_by_path() */
96 fun_del_ref(fun);
97
98 async_answer_1(iid, EOK, handle);
99}
100
101/** Get device match ID. */
102static void devman_fun_get_match_id(ipc_callid_t iid, ipc_call_t *icall)
103{
104 devman_handle_t handle = IPC_GET_ARG1(*icall);
105 size_t index = IPC_GET_ARG2(*icall);
106 void *buffer = NULL;
107
108 fun_node_t *fun = find_fun_node(&device_tree, handle);
109 if (fun == NULL) {
110 async_answer_0(iid, ENOMEM);
111 return;
112 }
113
114 ipc_callid_t data_callid;
115 size_t data_len;
116 if (!async_data_read_receive(&data_callid, &data_len)) {
117 async_answer_0(iid, EINVAL);
118 fun_del_ref(fun);
119 return;
120 }
121
122 buffer = malloc(data_len);
123 if (buffer == NULL) {
124 async_answer_0(data_callid, ENOMEM);
125 async_answer_0(iid, ENOMEM);
126 fun_del_ref(fun);
127 return;
128 }
129
130 fibril_rwlock_read_lock(&device_tree.rwlock);
131
132 /* Check function state */
133 if (fun->state == FUN_REMOVED)
134 goto error;
135
136 link_t *link = list_nth(&fun->match_ids.ids, index);
137 if (link == NULL)
138 goto error;
139
140 match_id_t *mid = list_get_instance(link, match_id_t, link);
141
142 size_t sent_length = str_size(mid->id);
143 if (sent_length > data_len) {
144 sent_length = data_len;
145 }
146
147 async_data_read_finalize(data_callid, mid->id, sent_length);
148 async_answer_1(iid, EOK, mid->score);
149
150 fibril_rwlock_read_unlock(&device_tree.rwlock);
151 fun_del_ref(fun);
152 free(buffer);
153
154 return;
155error:
156 fibril_rwlock_read_unlock(&device_tree.rwlock);
157 free(buffer);
158
159 async_answer_0(data_callid, ENOENT);
160 async_answer_0(iid, ENOENT);
161 fun_del_ref(fun);
162}
163
164/** Get device name. */
165static void devman_fun_get_name(ipc_callid_t iid, ipc_call_t *icall)
166{
167 devman_handle_t handle = IPC_GET_ARG1(*icall);
168
169 fun_node_t *fun = find_fun_node(&device_tree, handle);
170 if (fun == NULL) {
171 async_answer_0(iid, ENOMEM);
172 return;
173 }
174
175 ipc_callid_t data_callid;
176 size_t data_len;
177 if (!async_data_read_receive(&data_callid, &data_len)) {
178 async_answer_0(iid, EINVAL);
179 fun_del_ref(fun);
180 return;
181 }
182
183 void *buffer = malloc(data_len);
184 if (buffer == NULL) {
185 async_answer_0(data_callid, ENOMEM);
186 async_answer_0(iid, ENOMEM);
187 fun_del_ref(fun);
188 return;
189 }
190
191 fibril_rwlock_read_lock(&device_tree.rwlock);
192
193 /* Check function state */
194 if (fun->state == FUN_REMOVED) {
195 fibril_rwlock_read_unlock(&device_tree.rwlock);
196 free(buffer);
197
198 async_answer_0(data_callid, ENOENT);
199 async_answer_0(iid, ENOENT);
200 fun_del_ref(fun);
201 return;
202 }
203
204 size_t sent_length = str_size(fun->name);
205 if (sent_length > data_len) {
206 sent_length = data_len;
207 }
208
209 async_data_read_finalize(data_callid, fun->name, sent_length);
210 async_answer_0(iid, EOK);
211
212 fibril_rwlock_read_unlock(&device_tree.rwlock);
213 fun_del_ref(fun);
214 free(buffer);
215}
216
217/** Get function driver name. */
218static void devman_fun_get_driver_name(ipc_callid_t iid, ipc_call_t *icall)
219{
220 devman_handle_t handle = IPC_GET_ARG1(*icall);
221
222 fun_node_t *fun = find_fun_node(&device_tree, handle);
223 if (fun == NULL) {
224 async_answer_0(iid, ENOMEM);
225 return;
226 }
227
228 ipc_callid_t data_callid;
229 size_t data_len;
230 if (!async_data_read_receive(&data_callid, &data_len)) {
231 async_answer_0(iid, EINVAL);
232 fun_del_ref(fun);
233 return;
234 }
235
236 void *buffer = malloc(data_len);
237 if (buffer == NULL) {
238 async_answer_0(data_callid, ENOMEM);
239 async_answer_0(iid, ENOMEM);
240 fun_del_ref(fun);
241 return;
242 }
243
244 fibril_rwlock_read_lock(&device_tree.rwlock);
245
246 /* Check function state */
247 if (fun->state == FUN_REMOVED) {
248 fibril_rwlock_read_unlock(&device_tree.rwlock);
249 free(buffer);
250
251 async_answer_0(data_callid, ENOENT);
252 async_answer_0(iid, ENOENT);
253 fun_del_ref(fun);
254 return;
255 }
256
257 /* Check whether function has a driver */
258 if (fun->child == NULL || fun->child->drv == NULL) {
259 fibril_rwlock_read_unlock(&device_tree.rwlock);
260 free(buffer);
261
262 async_answer_0(data_callid, EINVAL);
263 async_answer_0(iid, EINVAL);
264 fun_del_ref(fun);
265 return;
266 }
267
268 size_t sent_length = str_size(fun->child->drv->name);
269 if (sent_length > data_len) {
270 sent_length = data_len;
271 }
272
273 async_data_read_finalize(data_callid, fun->child->drv->name,
274 sent_length);
275 async_answer_0(iid, EOK);
276
277 fibril_rwlock_read_unlock(&device_tree.rwlock);
278 fun_del_ref(fun);
279 free(buffer);
280}
281
282/** Get device path. */
283static void devman_fun_get_path(ipc_callid_t iid, ipc_call_t *icall)
284{
285 devman_handle_t handle = IPC_GET_ARG1(*icall);
286
287 fun_node_t *fun = find_fun_node(&device_tree, handle);
288 if (fun == NULL) {
289 async_answer_0(iid, ENOMEM);
290 return;
291 }
292
293 ipc_callid_t data_callid;
294 size_t data_len;
295 if (!async_data_read_receive(&data_callid, &data_len)) {
296 async_answer_0(iid, EINVAL);
297 fun_del_ref(fun);
298 return;
299 }
300
301 void *buffer = malloc(data_len);
302 if (buffer == NULL) {
303 async_answer_0(data_callid, ENOMEM);
304 async_answer_0(iid, ENOMEM);
305 fun_del_ref(fun);
306 return;
307 }
308
309 fibril_rwlock_read_lock(&device_tree.rwlock);
310
311 /* Check function state */
312 if (fun->state == FUN_REMOVED) {
313 fibril_rwlock_read_unlock(&device_tree.rwlock);
314 free(buffer);
315
316 async_answer_0(data_callid, ENOENT);
317 async_answer_0(iid, ENOENT);
318 fun_del_ref(fun);
319 return;
320 }
321
322 size_t sent_length = str_size(fun->pathname);
323 if (sent_length > data_len) {
324 sent_length = data_len;
325 }
326
327 async_data_read_finalize(data_callid, fun->pathname, sent_length);
328 async_answer_0(iid, EOK);
329
330 fibril_rwlock_read_unlock(&device_tree.rwlock);
331 fun_del_ref(fun);
332 free(buffer);
333}
334
335/** Get handle for parent function of a device. */
336static void devman_dev_get_parent(ipc_callid_t iid, ipc_call_t *icall)
337{
338 dev_node_t *dev;
339
340 fibril_rwlock_read_lock(&device_tree.rwlock);
341
342 dev = find_dev_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
343 if (dev == NULL || dev->state == DEVICE_REMOVED) {
344 fibril_rwlock_read_unlock(&device_tree.rwlock);
345 async_answer_0(iid, ENOENT);
346 return;
347 }
348
349 if (dev->pfun == NULL) {
350 fibril_rwlock_read_unlock(&device_tree.rwlock);
351 async_answer_0(iid, ENOENT);
352 return;
353 }
354
355 async_answer_1(iid, EOK, dev->pfun->handle);
356
357 fibril_rwlock_read_unlock(&device_tree.rwlock);
358}
359
360static void devman_dev_get_functions(ipc_callid_t iid, ipc_call_t *icall)
361{
362 ipc_callid_t callid;
363 size_t size;
364 size_t act_size;
365 int rc;
366
367 if (!async_data_read_receive(&callid, &size)) {
368 async_answer_0(callid, EREFUSED);
369 async_answer_0(iid, EREFUSED);
370 return;
371 }
372
373 fibril_rwlock_read_lock(&device_tree.rwlock);
374
375 dev_node_t *dev = find_dev_node_no_lock(&device_tree,
376 IPC_GET_ARG1(*icall));
377 if (dev == NULL || dev->state == DEVICE_REMOVED) {
378 fibril_rwlock_read_unlock(&device_tree.rwlock);
379 async_answer_0(callid, ENOENT);
380 async_answer_0(iid, ENOENT);
381 return;
382 }
383
384 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
385 if (hdl_buf == NULL) {
386 fibril_rwlock_read_unlock(&device_tree.rwlock);
387 async_answer_0(callid, ENOMEM);
388 async_answer_0(iid, ENOMEM);
389 return;
390 }
391
392 rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size);
393 if (rc != EOK) {
394 fibril_rwlock_read_unlock(&device_tree.rwlock);
395 async_answer_0(callid, rc);
396 async_answer_0(iid, rc);
397 return;
398 }
399
400 fibril_rwlock_read_unlock(&device_tree.rwlock);
401
402 int retval = async_data_read_finalize(callid, hdl_buf, size);
403 free(hdl_buf);
404
405 async_answer_1(iid, retval, act_size);
406}
407
408/** Get handle for child device of a function. */
409static void devman_fun_get_child(ipc_callid_t iid, ipc_call_t *icall)
410{
411 fun_node_t *fun;
412
413 fibril_rwlock_read_lock(&device_tree.rwlock);
414
415 fun = find_fun_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
416 if (fun == NULL || fun->state == FUN_REMOVED) {
417 fibril_rwlock_read_unlock(&device_tree.rwlock);
418 async_answer_0(iid, ENOENT);
419 return;
420 }
421
422 if (fun->child == NULL) {
423 fibril_rwlock_read_unlock(&device_tree.rwlock);
424 async_answer_0(iid, ENOENT);
425 return;
426 }
427
428 async_answer_1(iid, EOK, fun->child->handle);
429
430 fibril_rwlock_read_unlock(&device_tree.rwlock);
431}
432
433/** Online function.
434 *
435 * Send a request to online a function to the responsible driver.
436 * The driver may offline other functions if necessary (i.e. if the state
437 * of this function is linked to state of another function somehow).
438 */
439static void devman_fun_online(ipc_callid_t iid, ipc_call_t *icall)
440{
441 fun_node_t *fun;
442 int rc;
443
444 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
445 if (fun == NULL) {
446 async_answer_0(iid, ENOENT);
447 return;
448 }
449
450 rc = driver_fun_online(&device_tree, fun);
451 fun_del_ref(fun);
452
453 async_answer_0(iid, rc);
454}
455
456/** Offline function.
457 *
458 * Send a request to offline a function to the responsible driver. As
459 * a result the subtree rooted at that function should be cleanly
460 * detatched. The driver may offline other functions if necessary
461 * (i.e. if the state of this function is linked to state of another
462 * function somehow).
463 */
464static void devman_fun_offline(ipc_callid_t iid, ipc_call_t *icall)
465{
466 fun_node_t *fun;
467 int rc;
468
469 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
470 if (fun == NULL) {
471 async_answer_0(iid, ENOENT);
472 return;
473 }
474
475 rc = driver_fun_offline(&device_tree, fun);
476 fun_del_ref(fun);
477
478 async_answer_0(iid, rc);
479}
480
481/** Find handle for the function instance identified by its service ID. */
482static void devman_fun_sid_to_handle(ipc_callid_t iid, ipc_call_t *icall)
483{
484 fun_node_t *fun;
485
486 fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));
487
488 if (fun == NULL) {
489 async_answer_0(iid, ENOENT);
490 return;
491 }
492
493 fibril_rwlock_read_lock(&device_tree.rwlock);
494
495 /* Check function state */
496 if (fun->state == FUN_REMOVED) {
497 fibril_rwlock_read_unlock(&device_tree.rwlock);
498 async_answer_0(iid, ENOENT);
499 return;
500 }
501
502 async_answer_1(iid, EOK, fun->handle);
503 fibril_rwlock_read_unlock(&device_tree.rwlock);
504 fun_del_ref(fun);
505}
506
507/** Get list of all registered drivers. */
508static void devman_get_drivers(ipc_callid_t iid, ipc_call_t *icall)
509{
510 ipc_callid_t callid;
511 size_t size;
512 size_t act_size;
513 int rc;
514
515 if (!async_data_read_receive(&callid, &size)) {
516 async_answer_0(iid, EREFUSED);
517 return;
518 }
519
520 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
521 if (hdl_buf == NULL) {
522 async_answer_0(callid, ENOMEM);
523 async_answer_0(iid, ENOMEM);
524 return;
525 }
526
527 rc = driver_get_list(&drivers_list, hdl_buf, size, &act_size);
528 if (rc != EOK) {
529 async_answer_0(callid, rc);
530 async_answer_0(iid, rc);
531 return;
532 }
533
534 int retval = async_data_read_finalize(callid, hdl_buf, size);
535 free(hdl_buf);
536
537 async_answer_1(iid, retval, act_size);
538}
539
540static void devman_driver_get_devices(ipc_callid_t iid, ipc_call_t *icall)
541{
542 ipc_callid_t callid;
543 size_t size;
544 size_t act_size;
545 int rc;
546
547 if (!async_data_read_receive(&callid, &size)) {
548 async_answer_0(iid, EREFUSED);
549 return;
550 }
551
552 driver_t *drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
553 if (drv == NULL) {
554 async_answer_0(callid, ENOENT);
555 async_answer_0(iid, ENOENT);
556 return;
557 }
558
559 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
560 if (hdl_buf == NULL) {
561 async_answer_0(callid, ENOMEM);
562 async_answer_0(iid, ENOMEM);
563 return;
564 }
565
566 rc = driver_get_devices(drv, hdl_buf, size, &act_size);
567 if (rc != EOK) {
568 fibril_rwlock_read_unlock(&device_tree.rwlock);
569 async_answer_0(callid, rc);
570 async_answer_0(iid, rc);
571 return;
572 }
573
574 int retval = async_data_read_finalize(callid, hdl_buf, size);
575 free(hdl_buf);
576
577 async_answer_1(iid, retval, act_size);
578}
579
580
581/** Find driver by name. */
582static void devman_driver_get_handle(ipc_callid_t iid, ipc_call_t *icall)
583{
584 char *drvname;
585
586 int rc = async_data_write_accept((void **) &drvname, true, 0, 0, 0, 0);
587 if (rc != EOK) {
588 async_answer_0(iid, rc);
589 return;
590 }
591
592 driver_t *driver = driver_find_by_name(&drivers_list, drvname);
593
594 free(drvname);
595
596 if (driver == NULL) {
597 async_answer_0(iid, ENOENT);
598 return;
599 }
600
601 async_answer_1(iid, EOK, driver->handle);
602}
603
604/** Get driver match ID. */
605static void devman_driver_get_match_id(ipc_callid_t iid, ipc_call_t *icall)
606{
607 devman_handle_t handle = IPC_GET_ARG1(*icall);
608 size_t index = IPC_GET_ARG2(*icall);
609
610 driver_t *drv = driver_find(&drivers_list, handle);
611 if (drv == NULL) {
612 async_answer_0(iid, ENOMEM);
613 return;
614 }
615
616 ipc_callid_t data_callid;
617 size_t data_len;
618 if (!async_data_read_receive(&data_callid, &data_len)) {
619 async_answer_0(iid, EINVAL);
620 return;
621 }
622
623 void *buffer = malloc(data_len);
624 if (buffer == NULL) {
625 async_answer_0(data_callid, ENOMEM);
626 async_answer_0(iid, ENOMEM);
627 return;
628 }
629
630 fibril_mutex_lock(&drv->driver_mutex);
631 link_t *link = list_nth(&drv->match_ids.ids, index);
632 if (link == NULL) {
633 fibril_mutex_unlock(&drv->driver_mutex);
634 free(buffer);
635 async_answer_0(data_callid, ENOMEM);
636 async_answer_0(iid, ENOMEM);
637 return;
638 }
639
640 match_id_t *mid = list_get_instance(link, match_id_t, link);
641
642 size_t sent_length = str_size(mid->id);
643 if (sent_length > data_len) {
644 sent_length = data_len;
645 }
646
647 async_data_read_finalize(data_callid, mid->id, sent_length);
648 async_answer_1(iid, EOK, mid->score);
649
650 fibril_mutex_unlock(&drv->driver_mutex);
651
652 free(buffer);
653}
654
655/** Get driver name. */
656static void devman_driver_get_name(ipc_callid_t iid, ipc_call_t *icall)
657{
658 devman_handle_t handle = IPC_GET_ARG1(*icall);
659
660 driver_t *drv = driver_find(&drivers_list, handle);
661 if (drv == NULL) {
662 async_answer_0(iid, ENOMEM);
663 return;
664 }
665
666 ipc_callid_t data_callid;
667 size_t data_len;
668 if (!async_data_read_receive(&data_callid, &data_len)) {
669 async_answer_0(iid, EINVAL);
670 return;
671 }
672
673 void *buffer = malloc(data_len);
674 if (buffer == NULL) {
675 async_answer_0(data_callid, ENOMEM);
676 async_answer_0(iid, ENOMEM);
677 return;
678 }
679
680 fibril_mutex_lock(&drv->driver_mutex);
681
682 size_t sent_length = str_size(drv->name);
683 if (sent_length > data_len) {
684 sent_length = data_len;
685 }
686
687 async_data_read_finalize(data_callid, drv->name, sent_length);
688 async_answer_0(iid, EOK);
689
690 fibril_mutex_unlock(&drv->driver_mutex);
691
692 free(buffer);
693}
694
695/** Get driver state. */
696static void devman_driver_get_state(ipc_callid_t iid, ipc_call_t *icall)
697{
698 driver_t *drv;
699
700 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
701 if (drv == NULL) {
702 async_answer_0(iid, ENOENT);
703 return;
704 }
705
706 async_answer_1(iid, EOK, (sysarg_t) drv->state);
707}
708
709/** Forcibly load a driver. */
710static void devman_driver_load(ipc_callid_t iid, ipc_call_t *icall)
711{
712 driver_t *drv;
713 int rc;
714
715 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
716 if (drv == NULL) {
717 async_answer_0(iid, ENOENT);
718 return;
719 }
720
721 fibril_mutex_lock(&drv->driver_mutex);
722 rc = start_driver(drv) ? EOK : EIO;
723 fibril_mutex_unlock(&drv->driver_mutex);
724
725 async_answer_0(iid, rc);
726}
727
728/** Unload a driver by user request. */
729static void devman_driver_unload(ipc_callid_t iid, ipc_call_t *icall)
730{
731 driver_t *drv;
732 int rc;
733
734 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
735 if (drv == NULL) {
736 async_answer_0(iid, ENOENT);
737 return;
738 }
739
740 fibril_mutex_lock(&drv->driver_mutex);
741 rc = stop_driver(drv);
742 fibril_mutex_unlock(&drv->driver_mutex);
743
744 async_answer_0(iid, rc);
745}
746
747/** Function for handling connections from a client to the device manager. */
748void devman_connection_client(ipc_callid_t iid, ipc_call_t *icall, void *arg)
749{
750 /* Accept connection. */
751 async_answer_0(iid, EOK);
752
753 while (true) {
754 ipc_call_t call;
755 ipc_callid_t callid = async_get_call(&call);
756
757 if (!IPC_GET_IMETHOD(call))
758 break;
759
760 switch (IPC_GET_IMETHOD(call)) {
761 case DEVMAN_DEVICE_GET_HANDLE:
762 devman_function_get_handle(callid, &call);
763 break;
764 case DEVMAN_DEV_GET_PARENT:
765 devman_dev_get_parent(callid, &call);
766 break;
767 case DEVMAN_DEV_GET_FUNCTIONS:
768 devman_dev_get_functions(callid, &call);
769 break;
770 case DEVMAN_FUN_GET_CHILD:
771 devman_fun_get_child(callid, &call);
772 break;
773 case DEVMAN_FUN_GET_MATCH_ID:
774 devman_fun_get_match_id(callid, &call);
775 break;
776 case DEVMAN_FUN_GET_NAME:
777 devman_fun_get_name(callid, &call);
778 break;
779 case DEVMAN_FUN_GET_DRIVER_NAME:
780 devman_fun_get_driver_name(callid, &call);
781 break;
782 case DEVMAN_FUN_GET_PATH:
783 devman_fun_get_path(callid, &call);
784 break;
785 case DEVMAN_FUN_ONLINE:
786 devman_fun_online(callid, &call);
787 break;
788 case DEVMAN_FUN_OFFLINE:
789 devman_fun_offline(callid, &call);
790 break;
791 case DEVMAN_FUN_SID_TO_HANDLE:
792 devman_fun_sid_to_handle(callid, &call);
793 break;
794 case DEVMAN_GET_DRIVERS:
795 devman_get_drivers(callid, &call);
796 break;
797 case DEVMAN_DRIVER_GET_DEVICES:
798 devman_driver_get_devices(callid, &call);
799 break;
800 case DEVMAN_DRIVER_GET_HANDLE:
801 devman_driver_get_handle(callid, &call);
802 break;
803 case DEVMAN_DRIVER_GET_MATCH_ID:
804 devman_driver_get_match_id(callid, &call);
805 break;
806 case DEVMAN_DRIVER_GET_NAME:
807 devman_driver_get_name(callid, &call);
808 break;
809 case DEVMAN_DRIVER_GET_STATE:
810 devman_driver_get_state(callid, &call);
811 break;
812 case DEVMAN_DRIVER_LOAD:
813 devman_driver_load(callid, &call);
814 break;
815 case DEVMAN_DRIVER_UNLOAD:
816 devman_driver_unload(callid, &call);
817 break;
818 default:
819 async_answer_0(callid, ENOENT);
820 }
821 }
822}
823
824
825/** @}
826 */
Note: See TracBrowser for help on using the repository browser.