source: mainline/uspace/srv/devman/client_conn.c@ faf19d4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since faf19d4 was 6769005, checked in by Jakub Jermar <jakub@…>, 7 years ago

Use user-defined labels instead of phone hashes

This commit changes the way how the async framework maps incomming calls
to connections. Instead of abusing the kernel addresses of attached
phones as identifiers, the IPC_M_CONNECT_TO_ME and IPC_M_CONNECT_ME_TO
messages allow the server to specify an arbitrary label which is
remembered in the connected phone and consequently imprinted on each
call which is routed through this phone.

The async framework uses the address of the connection structure as the
label. This removes the need for a connection hash table because each
incoming call already remembers the connection in its label.

To disambiguate this new label and the other user-defined label used for
answers, the call structure now has the request_label member for the
former and answer_label member for the latter.

This commit also moves the kernel definition of ipc_data_t to abi/ and
removes the uspace redefinition thereof. Finally, when forwarding the
IPC_M_CONNECT_TO_ME call, the phone capability and the kernel object
allocated in request_process are now correctly disposed of.

  • Property mode set to 100644
File size: 18.5 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 * @addtogroup devman
32 * @{
33 */
34
35/** @file
36 */
37
38#include <inttypes.h>
39#include <assert.h>
40#include <ns.h>
41#include <async.h>
42#include <stdio.h>
43#include <errno.h>
44#include <str_error.h>
45#include <stdbool.h>
46#include <fibril_synch.h>
47#include <stdlib.h>
48#include <str.h>
49#include <ctype.h>
50#include <ipc/devman.h>
51
52#include "client_conn.h"
53#include "dev.h"
54#include "devman.h"
55#include "driver.h"
56#include "fun.h"
57#include "loc.h"
58#include "main.h"
59
60/** Find handle for the device instance identified by the device's path in the
61 * device tree.
62 */
63static void devman_function_get_handle(ipc_call_t *icall)
64{
65 char *pathname;
66 devman_handle_t handle;
67
68 errno_t rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0);
69 if (rc != EOK) {
70 async_answer_0(icall, 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(icall, 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(icall, 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(icall, EOK, handle);
99}
100
101/** Get device match ID. */
102static void devman_fun_get_match_id(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(icall, ENOMEM);
111 return;
112 }
113
114 ipc_call_t data;
115 size_t data_len;
116 if (!async_data_read_receive(&data, &data_len)) {
117 async_answer_0(icall, EINVAL);
118 fun_del_ref(fun);
119 return;
120 }
121
122 buffer = malloc(data_len);
123 if (buffer == NULL) {
124 async_answer_0(&data, ENOMEM);
125 async_answer_0(icall, 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, mid->id, sent_length);
148 async_answer_1(icall, 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, ENOENT);
160 async_answer_0(icall, ENOENT);
161 fun_del_ref(fun);
162}
163
164/** Get device name. */
165static void devman_fun_get_name(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(icall, ENOMEM);
172 return;
173 }
174
175 ipc_call_t data;
176 size_t data_len;
177 if (!async_data_read_receive(&data, &data_len)) {
178 async_answer_0(icall, 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, ENOMEM);
186 async_answer_0(icall, 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, ENOENT);
199 async_answer_0(icall, 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, fun->name, sent_length);
210 async_answer_0(icall, 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_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(icall, ENOMEM);
225 return;
226 }
227
228 ipc_call_t data;
229 size_t data_len;
230 if (!async_data_read_receive(&data, &data_len)) {
231 async_answer_0(icall, 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, ENOMEM);
239 async_answer_0(icall, 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, ENOENT);
252 async_answer_0(icall, 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, EINVAL);
263 async_answer_0(icall, 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, fun->child->drv->name,
274 sent_length);
275 async_answer_0(icall, 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_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(icall, ENOMEM);
290 return;
291 }
292
293 ipc_call_t data;
294 size_t data_len;
295 if (!async_data_read_receive(&data, &data_len)) {
296 async_answer_0(icall, 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, ENOMEM);
304 async_answer_0(icall, 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, ENOENT);
317 async_answer_0(icall, 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, fun->pathname, sent_length);
328 async_answer_0(icall, 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_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(icall, ENOENT);
346 return;
347 }
348
349 if (dev->pfun == NULL) {
350 fibril_rwlock_read_unlock(&device_tree.rwlock);
351 async_answer_0(icall, ENOENT);
352 return;
353 }
354
355 async_answer_1(icall, EOK, dev->pfun->handle);
356
357 fibril_rwlock_read_unlock(&device_tree.rwlock);
358}
359
360static void devman_dev_get_functions(ipc_call_t *icall)
361{
362 ipc_call_t call;
363 size_t size;
364 size_t act_size;
365 errno_t rc;
366
367 if (!async_data_read_receive(&call, &size)) {
368 async_answer_0(&call, EREFUSED);
369 async_answer_0(icall, 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(&call, ENOENT);
380 async_answer_0(icall, 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(&call, ENOMEM);
388 async_answer_0(icall, 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(&call, rc);
396 async_answer_0(icall, rc);
397 return;
398 }
399
400 fibril_rwlock_read_unlock(&device_tree.rwlock);
401
402 errno_t retval = async_data_read_finalize(&call, hdl_buf, size);
403 free(hdl_buf);
404
405 async_answer_1(icall, retval, act_size);
406}
407
408/** Get handle for child device of a function. */
409static void devman_fun_get_child(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(icall, ENOENT);
419 return;
420 }
421
422 if (fun->child == NULL) {
423 fibril_rwlock_read_unlock(&device_tree.rwlock);
424 async_answer_0(icall, ENOENT);
425 return;
426 }
427
428 async_answer_1(icall, 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_call_t *icall)
440{
441 fun_node_t *fun;
442 errno_t rc;
443
444 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
445 if (fun == NULL) {
446 async_answer_0(icall, ENOENT);
447 return;
448 }
449
450 rc = driver_fun_online(&device_tree, fun);
451 fun_del_ref(fun);
452
453 async_answer_0(icall, 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_call_t *icall)
465{
466 fun_node_t *fun;
467 errno_t rc;
468
469 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
470 if (fun == NULL) {
471 async_answer_0(icall, ENOENT);
472 return;
473 }
474
475 rc = driver_fun_offline(&device_tree, fun);
476 fun_del_ref(fun);
477
478 async_answer_0(icall, rc);
479}
480
481/** Find handle for the function instance identified by its service ID. */
482static void devman_fun_sid_to_handle(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(icall, 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(icall, ENOENT);
499 return;
500 }
501
502 async_answer_1(icall, 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_call_t *icall)
509{
510 ipc_call_t call;
511 size_t size;
512 size_t act_size;
513 errno_t rc;
514
515 if (!async_data_read_receive(&call, &size)) {
516 async_answer_0(icall, 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(&call, ENOMEM);
523 async_answer_0(icall, 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(&call, rc);
530 async_answer_0(icall, rc);
531 return;
532 }
533
534 errno_t retval = async_data_read_finalize(&call, hdl_buf, size);
535 free(hdl_buf);
536
537 async_answer_1(icall, retval, act_size);
538}
539
540static void devman_driver_get_devices(ipc_call_t *icall)
541{
542 ipc_call_t call;
543 size_t size;
544 size_t act_size;
545 errno_t rc;
546
547 if (!async_data_read_receive(&call, &size)) {
548 async_answer_0(icall, 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(&call, ENOENT);
555 async_answer_0(icall, 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(&call, ENOMEM);
562 async_answer_0(icall, 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(&call, rc);
570 async_answer_0(icall, rc);
571 return;
572 }
573
574 errno_t retval = async_data_read_finalize(&call, hdl_buf, size);
575 free(hdl_buf);
576
577 async_answer_1(icall, retval, act_size);
578}
579
580/** Find driver by name. */
581static void devman_driver_get_handle(ipc_call_t *icall)
582{
583 char *drvname;
584
585 errno_t rc = async_data_write_accept((void **) &drvname, true, 0, 0, 0, 0);
586 if (rc != EOK) {
587 async_answer_0(icall, rc);
588 return;
589 }
590
591 driver_t *driver = driver_find_by_name(&drivers_list, drvname);
592
593 free(drvname);
594
595 if (driver == NULL) {
596 async_answer_0(icall, ENOENT);
597 return;
598 }
599
600 async_answer_1(icall, EOK, driver->handle);
601}
602
603/** Get driver match ID. */
604static void devman_driver_get_match_id(ipc_call_t *icall)
605{
606 devman_handle_t handle = IPC_GET_ARG1(*icall);
607 size_t index = IPC_GET_ARG2(*icall);
608
609 driver_t *drv = driver_find(&drivers_list, handle);
610 if (drv == NULL) {
611 async_answer_0(icall, ENOMEM);
612 return;
613 }
614
615 ipc_call_t data;
616 size_t data_len;
617 if (!async_data_read_receive(&data, &data_len)) {
618 async_answer_0(icall, EINVAL);
619 return;
620 }
621
622 void *buffer = malloc(data_len);
623 if (buffer == NULL) {
624 async_answer_0(&data, ENOMEM);
625 async_answer_0(icall, ENOMEM);
626 return;
627 }
628
629 fibril_mutex_lock(&drv->driver_mutex);
630 link_t *link = list_nth(&drv->match_ids.ids, index);
631 if (link == NULL) {
632 fibril_mutex_unlock(&drv->driver_mutex);
633 free(buffer);
634 async_answer_0(&data, ENOMEM);
635 async_answer_0(icall, ENOMEM);
636 return;
637 }
638
639 match_id_t *mid = list_get_instance(link, match_id_t, link);
640
641 size_t sent_length = str_size(mid->id);
642 if (sent_length > data_len) {
643 sent_length = data_len;
644 }
645
646 async_data_read_finalize(&data, mid->id, sent_length);
647 async_answer_1(icall, EOK, mid->score);
648
649 fibril_mutex_unlock(&drv->driver_mutex);
650
651 free(buffer);
652}
653
654/** Get driver name. */
655static void devman_driver_get_name(ipc_call_t *icall)
656{
657 devman_handle_t handle = IPC_GET_ARG1(*icall);
658
659 driver_t *drv = driver_find(&drivers_list, handle);
660 if (drv == NULL) {
661 async_answer_0(icall, ENOMEM);
662 return;
663 }
664
665 ipc_call_t data;
666 size_t data_len;
667 if (!async_data_read_receive(&data, &data_len)) {
668 async_answer_0(icall, EINVAL);
669 return;
670 }
671
672 void *buffer = malloc(data_len);
673 if (buffer == NULL) {
674 async_answer_0(&data, ENOMEM);
675 async_answer_0(icall, ENOMEM);
676 return;
677 }
678
679 fibril_mutex_lock(&drv->driver_mutex);
680
681 size_t sent_length = str_size(drv->name);
682 if (sent_length > data_len) {
683 sent_length = data_len;
684 }
685
686 async_data_read_finalize(&data, drv->name, sent_length);
687 async_answer_0(icall, EOK);
688
689 fibril_mutex_unlock(&drv->driver_mutex);
690
691 free(buffer);
692}
693
694/** Get driver state. */
695static void devman_driver_get_state(ipc_call_t *icall)
696{
697 driver_t *drv;
698
699 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
700 if (drv == NULL) {
701 async_answer_0(icall, ENOENT);
702 return;
703 }
704
705 async_answer_1(icall, EOK, (sysarg_t) drv->state);
706}
707
708/** Forcibly load a driver. */
709static void devman_driver_load(ipc_call_t *icall)
710{
711 driver_t *drv;
712 errno_t rc;
713
714 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
715 if (drv == NULL) {
716 async_answer_0(icall, ENOENT);
717 return;
718 }
719
720 fibril_mutex_lock(&drv->driver_mutex);
721 rc = start_driver(drv) ? EOK : EIO;
722 fibril_mutex_unlock(&drv->driver_mutex);
723
724 async_answer_0(icall, rc);
725}
726
727/** Unload a driver by user request. */
728static void devman_driver_unload(ipc_call_t *icall)
729{
730 driver_t *drv;
731 errno_t rc;
732
733 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
734 if (drv == NULL) {
735 async_answer_0(icall, ENOENT);
736 return;
737 }
738
739 fibril_mutex_lock(&drv->driver_mutex);
740 rc = stop_driver(drv);
741 fibril_mutex_unlock(&drv->driver_mutex);
742
743 async_answer_0(icall, rc);
744}
745
746/** Function for handling connections from a client to the device manager. */
747void devman_connection_client(ipc_call_t *icall, void *arg)
748{
749 /* Accept connection. */
750 async_answer_5(icall, EOK, 0, 0, 0, 0, async_get_label());
751
752 while (true) {
753 ipc_call_t call;
754 async_get_call(&call);
755
756 if (!IPC_GET_IMETHOD(call)) {
757 async_answer_0(&call, EOK);
758 break;
759 }
760
761 switch (IPC_GET_IMETHOD(call)) {
762 case DEVMAN_DEVICE_GET_HANDLE:
763 devman_function_get_handle(&call);
764 break;
765 case DEVMAN_DEV_GET_PARENT:
766 devman_dev_get_parent(&call);
767 break;
768 case DEVMAN_DEV_GET_FUNCTIONS:
769 devman_dev_get_functions(&call);
770 break;
771 case DEVMAN_FUN_GET_CHILD:
772 devman_fun_get_child(&call);
773 break;
774 case DEVMAN_FUN_GET_MATCH_ID:
775 devman_fun_get_match_id(&call);
776 break;
777 case DEVMAN_FUN_GET_NAME:
778 devman_fun_get_name(&call);
779 break;
780 case DEVMAN_FUN_GET_DRIVER_NAME:
781 devman_fun_get_driver_name(&call);
782 break;
783 case DEVMAN_FUN_GET_PATH:
784 devman_fun_get_path(&call);
785 break;
786 case DEVMAN_FUN_ONLINE:
787 devman_fun_online(&call);
788 break;
789 case DEVMAN_FUN_OFFLINE:
790 devman_fun_offline(&call);
791 break;
792 case DEVMAN_FUN_SID_TO_HANDLE:
793 devman_fun_sid_to_handle(&call);
794 break;
795 case DEVMAN_GET_DRIVERS:
796 devman_get_drivers(&call);
797 break;
798 case DEVMAN_DRIVER_GET_DEVICES:
799 devman_driver_get_devices(&call);
800 break;
801 case DEVMAN_DRIVER_GET_HANDLE:
802 devman_driver_get_handle(&call);
803 break;
804 case DEVMAN_DRIVER_GET_MATCH_ID:
805 devman_driver_get_match_id(&call);
806 break;
807 case DEVMAN_DRIVER_GET_NAME:
808 devman_driver_get_name(&call);
809 break;
810 case DEVMAN_DRIVER_GET_STATE:
811 devman_driver_get_state(&call);
812 break;
813 case DEVMAN_DRIVER_LOAD:
814 devman_driver_load(&call);
815 break;
816 case DEVMAN_DRIVER_UNLOAD:
817 devman_driver_unload(&call);
818 break;
819 default:
820 async_answer_0(&call, ENOENT);
821 }
822 }
823}
824
825/** @}
826 */
Note: See TracBrowser for help on using the repository browser.