source: mainline/uspace/srv/devman/client_conn.c@ 984a9ba

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 984a9ba was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • 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 * @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.
63 */
64static void devman_function_get_handle(ipc_call_t *icall)
65{
66 char *pathname;
67 devman_handle_t handle;
68
69 errno_t rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0);
70 if (rc != EOK) {
71 async_answer_0(icall, rc);
72 return;
73 }
74
75 fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname);
76
77 free(pathname);
78
79 if (fun == NULL) {
80 async_answer_0(icall, ENOENT);
81 return;
82 }
83
84 fibril_rwlock_read_lock(&device_tree.rwlock);
85
86 /* Check function state */
87 if (fun->state == FUN_REMOVED) {
88 fibril_rwlock_read_unlock(&device_tree.rwlock);
89 async_answer_0(icall, ENOENT);
90 return;
91 }
92 handle = fun->handle;
93
94 fibril_rwlock_read_unlock(&device_tree.rwlock);
95
96 /* Delete reference created above by find_fun_node_by_path() */
97 fun_del_ref(fun);
98
99 async_answer_1(icall, EOK, handle);
100}
101
102/** Get device match ID. */
103static void devman_fun_get_match_id(ipc_call_t *icall)
104{
105 devman_handle_t handle = IPC_GET_ARG1(*icall);
106 size_t index = IPC_GET_ARG2(*icall);
107 void *buffer = NULL;
108
109 fun_node_t *fun = find_fun_node(&device_tree, handle);
110 if (fun == NULL) {
111 async_answer_0(icall, ENOMEM);
112 return;
113 }
114
115 ipc_call_t data;
116 size_t data_len;
117 if (!async_data_read_receive(&data, &data_len)) {
118 async_answer_0(icall, EINVAL);
119 fun_del_ref(fun);
120 return;
121 }
122
123 buffer = malloc(data_len);
124 if (buffer == NULL) {
125 async_answer_0(&data, ENOMEM);
126 async_answer_0(icall, ENOMEM);
127 fun_del_ref(fun);
128 return;
129 }
130
131 fibril_rwlock_read_lock(&device_tree.rwlock);
132
133 /* Check function state */
134 if (fun->state == FUN_REMOVED)
135 goto error;
136
137 link_t *link = list_nth(&fun->match_ids.ids, index);
138 if (link == NULL)
139 goto error;
140
141 match_id_t *mid = list_get_instance(link, match_id_t, link);
142
143 size_t sent_length = str_size(mid->id);
144 if (sent_length > data_len) {
145 sent_length = data_len;
146 }
147
148 async_data_read_finalize(&data, mid->id, sent_length);
149 async_answer_1(icall, EOK, mid->score);
150
151 fibril_rwlock_read_unlock(&device_tree.rwlock);
152 fun_del_ref(fun);
153 free(buffer);
154
155 return;
156error:
157 fibril_rwlock_read_unlock(&device_tree.rwlock);
158 free(buffer);
159
160 async_answer_0(&data, ENOENT);
161 async_answer_0(icall, ENOENT);
162 fun_del_ref(fun);
163}
164
165/** Get device name. */
166static void devman_fun_get_name(ipc_call_t *icall)
167{
168 devman_handle_t handle = IPC_GET_ARG1(*icall);
169
170 fun_node_t *fun = find_fun_node(&device_tree, handle);
171 if (fun == NULL) {
172 async_answer_0(icall, ENOMEM);
173 return;
174 }
175
176 ipc_call_t data;
177 size_t data_len;
178 if (!async_data_read_receive(&data, &data_len)) {
179 async_answer_0(icall, EINVAL);
180 fun_del_ref(fun);
181 return;
182 }
183
184 void *buffer = malloc(data_len);
185 if (buffer == NULL) {
186 async_answer_0(&data, ENOMEM);
187 async_answer_0(icall, ENOMEM);
188 fun_del_ref(fun);
189 return;
190 }
191
192 fibril_rwlock_read_lock(&device_tree.rwlock);
193
194 /* Check function state */
195 if (fun->state == FUN_REMOVED) {
196 fibril_rwlock_read_unlock(&device_tree.rwlock);
197 free(buffer);
198
199 async_answer_0(&data, ENOENT);
200 async_answer_0(icall, ENOENT);
201 fun_del_ref(fun);
202 return;
203 }
204
205 size_t sent_length = str_size(fun->name);
206 if (sent_length > data_len) {
207 sent_length = data_len;
208 }
209
210 async_data_read_finalize(&data, fun->name, sent_length);
211 async_answer_0(icall, EOK);
212
213 fibril_rwlock_read_unlock(&device_tree.rwlock);
214 fun_del_ref(fun);
215 free(buffer);
216}
217
218/** Get function driver name. */
219static void devman_fun_get_driver_name(ipc_call_t *icall)
220{
221 devman_handle_t handle = IPC_GET_ARG1(*icall);
222
223 fun_node_t *fun = find_fun_node(&device_tree, handle);
224 if (fun == NULL) {
225 async_answer_0(icall, ENOMEM);
226 return;
227 }
228
229 ipc_call_t data;
230 size_t data_len;
231 if (!async_data_read_receive(&data, &data_len)) {
232 async_answer_0(icall, EINVAL);
233 fun_del_ref(fun);
234 return;
235 }
236
237 void *buffer = malloc(data_len);
238 if (buffer == NULL) {
239 async_answer_0(&data, ENOMEM);
240 async_answer_0(icall, ENOMEM);
241 fun_del_ref(fun);
242 return;
243 }
244
245 fibril_rwlock_read_lock(&device_tree.rwlock);
246
247 /* Check function state */
248 if (fun->state == FUN_REMOVED) {
249 fibril_rwlock_read_unlock(&device_tree.rwlock);
250 free(buffer);
251
252 async_answer_0(&data, ENOENT);
253 async_answer_0(icall, ENOENT);
254 fun_del_ref(fun);
255 return;
256 }
257
258 /* Check whether function has a driver */
259 if (fun->child == NULL || fun->child->drv == NULL) {
260 fibril_rwlock_read_unlock(&device_tree.rwlock);
261 free(buffer);
262
263 async_answer_0(&data, EINVAL);
264 async_answer_0(icall, EINVAL);
265 fun_del_ref(fun);
266 return;
267 }
268
269 size_t sent_length = str_size(fun->child->drv->name);
270 if (sent_length > data_len) {
271 sent_length = data_len;
272 }
273
274 async_data_read_finalize(&data, fun->child->drv->name,
275 sent_length);
276 async_answer_0(icall, EOK);
277
278 fibril_rwlock_read_unlock(&device_tree.rwlock);
279 fun_del_ref(fun);
280 free(buffer);
281}
282
283/** Get device path. */
284static void devman_fun_get_path(ipc_call_t *icall)
285{
286 devman_handle_t handle = IPC_GET_ARG1(*icall);
287
288 fun_node_t *fun = find_fun_node(&device_tree, handle);
289 if (fun == NULL) {
290 async_answer_0(icall, ENOMEM);
291 return;
292 }
293
294 ipc_call_t data;
295 size_t data_len;
296 if (!async_data_read_receive(&data, &data_len)) {
297 async_answer_0(icall, EINVAL);
298 fun_del_ref(fun);
299 return;
300 }
301
302 void *buffer = malloc(data_len);
303 if (buffer == NULL) {
304 async_answer_0(&data, ENOMEM);
305 async_answer_0(icall, ENOMEM);
306 fun_del_ref(fun);
307 return;
308 }
309
310 fibril_rwlock_read_lock(&device_tree.rwlock);
311
312 /* Check function state */
313 if (fun->state == FUN_REMOVED) {
314 fibril_rwlock_read_unlock(&device_tree.rwlock);
315 free(buffer);
316
317 async_answer_0(&data, ENOENT);
318 async_answer_0(icall, ENOENT);
319 fun_del_ref(fun);
320 return;
321 }
322
323 size_t sent_length = str_size(fun->pathname);
324 if (sent_length > data_len) {
325 sent_length = data_len;
326 }
327
328 async_data_read_finalize(&data, fun->pathname, sent_length);
329 async_answer_0(icall, EOK);
330
331 fibril_rwlock_read_unlock(&device_tree.rwlock);
332 fun_del_ref(fun);
333 free(buffer);
334}
335
336/** Get handle for parent function of a device. */
337static void devman_dev_get_parent(ipc_call_t *icall)
338{
339 dev_node_t *dev;
340
341 fibril_rwlock_read_lock(&device_tree.rwlock);
342
343 dev = find_dev_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
344 if (dev == NULL || dev->state == DEVICE_REMOVED) {
345 fibril_rwlock_read_unlock(&device_tree.rwlock);
346 async_answer_0(icall, ENOENT);
347 return;
348 }
349
350 if (dev->pfun == NULL) {
351 fibril_rwlock_read_unlock(&device_tree.rwlock);
352 async_answer_0(icall, ENOENT);
353 return;
354 }
355
356 async_answer_1(icall, EOK, dev->pfun->handle);
357
358 fibril_rwlock_read_unlock(&device_tree.rwlock);
359}
360
361static void devman_dev_get_functions(ipc_call_t *icall)
362{
363 ipc_call_t call;
364 size_t size;
365 size_t act_size;
366 errno_t rc;
367
368 if (!async_data_read_receive(&call, &size)) {
369 async_answer_0(&call, EREFUSED);
370 async_answer_0(icall, EREFUSED);
371 return;
372 }
373
374 fibril_rwlock_read_lock(&device_tree.rwlock);
375
376 dev_node_t *dev = find_dev_node_no_lock(&device_tree,
377 IPC_GET_ARG1(*icall));
378 if (dev == NULL || dev->state == DEVICE_REMOVED) {
379 fibril_rwlock_read_unlock(&device_tree.rwlock);
380 async_answer_0(&call, ENOENT);
381 async_answer_0(icall, ENOENT);
382 return;
383 }
384
385 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
386 if (hdl_buf == NULL) {
387 fibril_rwlock_read_unlock(&device_tree.rwlock);
388 async_answer_0(&call, ENOMEM);
389 async_answer_0(icall, ENOMEM);
390 return;
391 }
392
393 rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size);
394 if (rc != EOK) {
395 fibril_rwlock_read_unlock(&device_tree.rwlock);
396 async_answer_0(&call, rc);
397 async_answer_0(icall, rc);
398 return;
399 }
400
401 fibril_rwlock_read_unlock(&device_tree.rwlock);
402
403 errno_t retval = async_data_read_finalize(&call, hdl_buf, size);
404 free(hdl_buf);
405
406 async_answer_1(icall, retval, act_size);
407}
408
409/** Get handle for child device of a function. */
410static void devman_fun_get_child(ipc_call_t *icall)
411{
412 fun_node_t *fun;
413
414 fibril_rwlock_read_lock(&device_tree.rwlock);
415
416 fun = find_fun_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
417 if (fun == NULL || fun->state == FUN_REMOVED) {
418 fibril_rwlock_read_unlock(&device_tree.rwlock);
419 async_answer_0(icall, ENOENT);
420 return;
421 }
422
423 if (fun->child == NULL) {
424 fibril_rwlock_read_unlock(&device_tree.rwlock);
425 async_answer_0(icall, ENOENT);
426 return;
427 }
428
429 async_answer_1(icall, EOK, fun->child->handle);
430
431 fibril_rwlock_read_unlock(&device_tree.rwlock);
432}
433
434/** Online function.
435 *
436 * Send a request to online a function to the responsible driver.
437 * The driver may offline other functions if necessary (i.e. if the state
438 * of this function is linked to state of another function somehow).
439 */
440static void devman_fun_online(ipc_call_t *icall)
441{
442 fun_node_t *fun;
443 errno_t rc;
444
445 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
446 if (fun == NULL) {
447 async_answer_0(icall, ENOENT);
448 return;
449 }
450
451 rc = driver_fun_online(&device_tree, fun);
452 fun_del_ref(fun);
453
454 async_answer_0(icall, rc);
455}
456
457/** Offline function.
458 *
459 * Send a request to offline a function to the responsible driver. As
460 * a result the subtree rooted at that function should be cleanly
461 * detatched. The driver may offline other functions if necessary
462 * (i.e. if the state of this function is linked to state of another
463 * function somehow).
464 */
465static void devman_fun_offline(ipc_call_t *icall)
466{
467 fun_node_t *fun;
468 errno_t rc;
469
470 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
471 if (fun == NULL) {
472 async_answer_0(icall, ENOENT);
473 return;
474 }
475
476 rc = driver_fun_offline(&device_tree, fun);
477 fun_del_ref(fun);
478
479 async_answer_0(icall, rc);
480}
481
482/** Find handle for the function instance identified by its service ID. */
483static void devman_fun_sid_to_handle(ipc_call_t *icall)
484{
485 fun_node_t *fun;
486
487 fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));
488
489 if (fun == NULL) {
490 async_answer_0(icall, ENOENT);
491 return;
492 }
493
494 fibril_rwlock_read_lock(&device_tree.rwlock);
495
496 /* Check function state */
497 if (fun->state == FUN_REMOVED) {
498 fibril_rwlock_read_unlock(&device_tree.rwlock);
499 async_answer_0(icall, ENOENT);
500 return;
501 }
502
503 async_answer_1(icall, EOK, fun->handle);
504 fibril_rwlock_read_unlock(&device_tree.rwlock);
505 fun_del_ref(fun);
506}
507
508/** Get list of all registered drivers. */
509static void devman_get_drivers(ipc_call_t *icall)
510{
511 ipc_call_t call;
512 size_t size;
513 size_t act_size;
514 errno_t rc;
515
516 if (!async_data_read_receive(&call, &size)) {
517 async_answer_0(icall, EREFUSED);
518 return;
519 }
520
521 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
522 if (hdl_buf == NULL) {
523 async_answer_0(&call, ENOMEM);
524 async_answer_0(icall, ENOMEM);
525 return;
526 }
527
528 rc = driver_get_list(&drivers_list, hdl_buf, size, &act_size);
529 if (rc != EOK) {
530 async_answer_0(&call, rc);
531 async_answer_0(icall, rc);
532 return;
533 }
534
535 errno_t retval = async_data_read_finalize(&call, hdl_buf, size);
536 free(hdl_buf);
537
538 async_answer_1(icall, retval, act_size);
539}
540
541static void devman_driver_get_devices(ipc_call_t *icall)
542{
543 ipc_call_t call;
544 size_t size;
545 size_t act_size;
546 errno_t rc;
547
548 if (!async_data_read_receive(&call, &size)) {
549 async_answer_0(icall, EREFUSED);
550 return;
551 }
552
553 driver_t *drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
554 if (drv == NULL) {
555 async_answer_0(&call, ENOENT);
556 async_answer_0(icall, ENOENT);
557 return;
558 }
559
560 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size);
561 if (hdl_buf == NULL) {
562 async_answer_0(&call, ENOMEM);
563 async_answer_0(icall, ENOMEM);
564 return;
565 }
566
567 rc = driver_get_devices(drv, hdl_buf, size, &act_size);
568 if (rc != EOK) {
569 fibril_rwlock_read_unlock(&device_tree.rwlock);
570 async_answer_0(&call, rc);
571 async_answer_0(icall, rc);
572 return;
573 }
574
575 errno_t retval = async_data_read_finalize(&call, hdl_buf, size);
576 free(hdl_buf);
577
578 async_answer_1(icall, retval, act_size);
579}
580
581
582/** Find driver by name. */
583static void devman_driver_get_handle(ipc_call_t *icall)
584{
585 char *drvname;
586
587 errno_t rc = async_data_write_accept((void **) &drvname, true, 0, 0, 0, 0);
588 if (rc != EOK) {
589 async_answer_0(icall, rc);
590 return;
591 }
592
593 driver_t *driver = driver_find_by_name(&drivers_list, drvname);
594
595 free(drvname);
596
597 if (driver == NULL) {
598 async_answer_0(icall, ENOENT);
599 return;
600 }
601
602 async_answer_1(icall, EOK, driver->handle);
603}
604
605/** Get driver match ID. */
606static void devman_driver_get_match_id(ipc_call_t *icall)
607{
608 devman_handle_t handle = IPC_GET_ARG1(*icall);
609 size_t index = IPC_GET_ARG2(*icall);
610
611 driver_t *drv = driver_find(&drivers_list, handle);
612 if (drv == NULL) {
613 async_answer_0(icall, ENOMEM);
614 return;
615 }
616
617 ipc_call_t data;
618 size_t data_len;
619 if (!async_data_read_receive(&data, &data_len)) {
620 async_answer_0(icall, EINVAL);
621 return;
622 }
623
624 void *buffer = malloc(data_len);
625 if (buffer == NULL) {
626 async_answer_0(&data, ENOMEM);
627 async_answer_0(icall, ENOMEM);
628 return;
629 }
630
631 fibril_mutex_lock(&drv->driver_mutex);
632 link_t *link = list_nth(&drv->match_ids.ids, index);
633 if (link == NULL) {
634 fibril_mutex_unlock(&drv->driver_mutex);
635 free(buffer);
636 async_answer_0(&data, ENOMEM);
637 async_answer_0(icall, ENOMEM);
638 return;
639 }
640
641 match_id_t *mid = list_get_instance(link, match_id_t, link);
642
643 size_t sent_length = str_size(mid->id);
644 if (sent_length > data_len) {
645 sent_length = data_len;
646 }
647
648 async_data_read_finalize(&data, mid->id, sent_length);
649 async_answer_1(icall, EOK, mid->score);
650
651 fibril_mutex_unlock(&drv->driver_mutex);
652
653 free(buffer);
654}
655
656/** Get driver name. */
657static void devman_driver_get_name(ipc_call_t *icall)
658{
659 devman_handle_t handle = IPC_GET_ARG1(*icall);
660
661 driver_t *drv = driver_find(&drivers_list, handle);
662 if (drv == NULL) {
663 async_answer_0(icall, ENOMEM);
664 return;
665 }
666
667 ipc_call_t data;
668 size_t data_len;
669 if (!async_data_read_receive(&data, &data_len)) {
670 async_answer_0(icall, EINVAL);
671 return;
672 }
673
674 void *buffer = malloc(data_len);
675 if (buffer == NULL) {
676 async_answer_0(&data, ENOMEM);
677 async_answer_0(icall, ENOMEM);
678 return;
679 }
680
681 fibril_mutex_lock(&drv->driver_mutex);
682
683 size_t sent_length = str_size(drv->name);
684 if (sent_length > data_len) {
685 sent_length = data_len;
686 }
687
688 async_data_read_finalize(&data, drv->name, sent_length);
689 async_answer_0(icall, EOK);
690
691 fibril_mutex_unlock(&drv->driver_mutex);
692
693 free(buffer);
694}
695
696/** Get driver state. */
697static void devman_driver_get_state(ipc_call_t *icall)
698{
699 driver_t *drv;
700
701 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
702 if (drv == NULL) {
703 async_answer_0(icall, ENOENT);
704 return;
705 }
706
707 async_answer_1(icall, EOK, (sysarg_t) drv->state);
708}
709
710/** Forcibly load a driver. */
711static void devman_driver_load(ipc_call_t *icall)
712{
713 driver_t *drv;
714 errno_t rc;
715
716 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
717 if (drv == NULL) {
718 async_answer_0(icall, ENOENT);
719 return;
720 }
721
722 fibril_mutex_lock(&drv->driver_mutex);
723 rc = start_driver(drv) ? EOK : EIO;
724 fibril_mutex_unlock(&drv->driver_mutex);
725
726 async_answer_0(icall, rc);
727}
728
729/** Unload a driver by user request. */
730static void devman_driver_unload(ipc_call_t *icall)
731{
732 driver_t *drv;
733 errno_t rc;
734
735 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
736 if (drv == NULL) {
737 async_answer_0(icall, ENOENT);
738 return;
739 }
740
741 fibril_mutex_lock(&drv->driver_mutex);
742 rc = stop_driver(drv);
743 fibril_mutex_unlock(&drv->driver_mutex);
744
745 async_answer_0(icall, rc);
746}
747
748/** Function for handling connections from a client to the device manager. */
749void devman_connection_client(ipc_call_t *icall, void *arg)
750{
751 /* Accept connection. */
752 async_answer_0(icall, EOK);
753
754 while (true) {
755 ipc_call_t call;
756 async_get_call(&call);
757
758 if (!IPC_GET_IMETHOD(call))
759 break;
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.