source: mainline/uspace/srv/devmap/devmap.c@ c07af37

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

Handle pending lookups using only one fibril.

  • Property mode set to 100644
File size: 19.3 KB
Line 
1/*
2 * Copyright (c) 2007 Josef Cejka
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @defgroup devmap Device mapper.
31 * @brief HelenOS device mapper.
32 * @{
33 */
34
35/** @file
36 */
37
38#include <ipc/services.h>
39#include <ipc/ns.h>
40#include <async.h>
41#include <stdio.h>
42#include <errno.h>
43#include <bool.h>
44#include <fibril_sync.h>
45#include <stdlib.h>
46#include <string.h>
47#include <ipc/devmap.h>
48#include <assert.h>
49
50#define NAME "devmap"
51
52/** Representation of device driver.
53 *
54 * Each driver is responsible for a set of devices.
55 *
56 */
57typedef struct {
58 /** Pointers to previous and next drivers in linked list */
59 link_t drivers;
60 /** Pointer to the linked list of devices controlled by this driver */
61 link_t devices;
62 /** Phone asociated with this driver */
63 ipcarg_t phone;
64 /** Device driver name */
65 char *name;
66 /** Fibril mutex for list of devices owned by this driver */
67 fibril_mutex_t devices_mutex;
68} devmap_driver_t;
69
70/** Info about registered device
71 *
72 */
73typedef struct {
74 /** Pointer to the previous and next device in the list of all devices */
75 link_t devices;
76 /** Pointer to the previous and next device in the list of devices
77 owned by one driver */
78 link_t driver_devices;
79 /** Unique device identifier */
80 dev_handle_t handle;
81 /** Device name */
82 char *name;
83 /** Device driver handling this device */
84 devmap_driver_t *driver;
85} devmap_device_t;
86
87/** Pending lookup structure. */
88typedef struct {
89 link_t link;
90 char *name; /**< Device name */
91 ipc_callid_t callid; /**< Call ID waiting for the lookup */
92} pending_req_t;
93
94LIST_INITIALIZE(devices_list);
95LIST_INITIALIZE(drivers_list);
96LIST_INITIALIZE(pending_req);
97
98static bool pending_new_dev = false;
99static FIBRIL_CONDVAR_INITIALIZE(pending_cv);
100
101/* Locking order:
102 * drivers_list_mutex
103 * devices_list_mutex
104 * (devmap_driver_t *)->devices_mutex
105 * create_handle_mutex
106 **/
107
108static FIBRIL_MUTEX_INITIALIZE(devices_list_mutex);
109static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex);
110static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex);
111
112static dev_handle_t last_handle = 0;
113
114static dev_handle_t devmap_create_handle(void)
115{
116 /* TODO: allow reusing old handles after their unregistration
117 * and implement some version of LRU algorithm, avoid overflow
118 */
119
120 fibril_mutex_lock(&create_handle_mutex);
121 last_handle++;
122 fibril_mutex_unlock(&create_handle_mutex);
123
124 return last_handle;
125}
126
127/** Find device with given name.
128 *
129 */
130static devmap_device_t *devmap_device_find_name(const char *name)
131{
132 link_t *item = devices_list.next;
133 devmap_device_t *device = NULL;
134
135 while (item != &devices_list) {
136 device = list_get_instance(item, devmap_device_t, devices);
137 if (str_cmp(device->name, name) == 0)
138 break;
139 item = item->next;
140 }
141
142 if (item == &devices_list)
143 return NULL;
144
145 device = list_get_instance(item, devmap_device_t, devices);
146 return device;
147}
148
149/** Find device with given handle.
150 *
151 * @todo: use hash table
152 *
153 */
154static devmap_device_t *devmap_device_find_handle(dev_handle_t handle)
155{
156 fibril_mutex_lock(&devices_list_mutex);
157
158 link_t *item = (&devices_list)->next;
159 devmap_device_t *device = NULL;
160
161 while (item != &devices_list) {
162 device = list_get_instance(item, devmap_device_t, devices);
163 if (device->handle == handle)
164 break;
165 item = item->next;
166 }
167
168 if (item == &devices_list) {
169 fibril_mutex_unlock(&devices_list_mutex);
170 return NULL;
171 }
172
173 device = list_get_instance(item, devmap_device_t, devices);
174
175 fibril_mutex_unlock(&devices_list_mutex);
176
177 return device;
178}
179
180/**
181 * Unregister device and free it. It's assumed that driver's device list is
182 * already locked.
183 */
184static int devmap_device_unregister_core(devmap_device_t *device)
185{
186 list_remove(&(device->devices));
187 list_remove(&(device->driver_devices));
188
189 free(device->name);
190 free(device);
191
192 return EOK;
193}
194
195/**
196 * Read info about new driver and add it into linked list of registered
197 * drivers.
198 */
199static void devmap_driver_register(devmap_driver_t **odriver)
200{
201 *odriver = NULL;
202
203 ipc_call_t icall;
204 ipc_callid_t iid = async_get_call(&icall);
205
206 if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) {
207 ipc_answer_0(iid, EREFUSED);
208 return;
209 }
210
211 devmap_driver_t *driver = (devmap_driver_t *) malloc(sizeof(devmap_driver_t));
212
213 if (driver == NULL) {
214 ipc_answer_0(iid, ENOMEM);
215 return;
216 }
217
218 /*
219 * Get driver name
220 */
221 ipc_callid_t callid;
222 size_t name_size;
223 if (!ipc_data_write_receive(&callid, &name_size)) {
224 free(driver);
225 ipc_answer_0(callid, EREFUSED);
226 ipc_answer_0(iid, EREFUSED);
227 return;
228 }
229
230 if (name_size > DEVMAP_NAME_MAXLEN) {
231 free(driver);
232 ipc_answer_0(callid, EINVAL);
233 ipc_answer_0(iid, EREFUSED);
234 return;
235 }
236
237 /*
238 * Allocate buffer for device name.
239 */
240 driver->name = (char *) malloc(name_size + 1);
241 if (driver->name == NULL) {
242 free(driver);
243 ipc_answer_0(callid, ENOMEM);
244 ipc_answer_0(iid, EREFUSED);
245 return;
246 }
247
248 /*
249 * Send confirmation to sender and get data into buffer.
250 */
251 if (ipc_data_write_finalize(callid, driver->name, name_size) != EOK) {
252 free(driver->name);
253 free(driver);
254 ipc_answer_0(iid, EREFUSED);
255 return;
256 }
257
258 driver->name[name_size] = 0;
259
260 /* Initialize mutex for list of devices owned by this driver */
261 fibril_mutex_initialize(&driver->devices_mutex);
262
263 /*
264 * Initialize list of asociated devices
265 */
266 list_initialize(&driver->devices);
267
268 /*
269 * Create connection to the driver
270 */
271 ipc_call_t call;
272 callid = async_get_call(&call);
273
274 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
275 ipc_answer_0(callid, ENOTSUP);
276
277 free(driver->name);
278 free(driver);
279 ipc_answer_0(iid, ENOTSUP);
280 return;
281 }
282
283 driver->phone = IPC_GET_ARG5(call);
284
285 ipc_answer_0(callid, EOK);
286
287 list_initialize(&(driver->drivers));
288
289 fibril_mutex_lock(&drivers_list_mutex);
290
291 /* TODO:
292 * check that no driver with name equal to driver->name is registered
293 */
294
295 /*
296 * Insert new driver into list of registered drivers
297 */
298 list_append(&(driver->drivers), &drivers_list);
299 fibril_mutex_unlock(&drivers_list_mutex);
300
301 ipc_answer_0(iid, EOK);
302
303 *odriver = driver;
304}
305
306/**
307 * Unregister device driver, unregister all its devices and free driver
308 * structure.
309 *
310 */
311static int devmap_driver_unregister(devmap_driver_t *driver)
312{
313 if (driver == NULL)
314 return EEXISTS;
315
316 fibril_mutex_lock(&drivers_list_mutex);
317
318 if (driver->phone != 0)
319 ipc_hangup(driver->phone);
320
321 /* Remove it from list of drivers */
322 list_remove(&(driver->drivers));
323
324 /* Unregister all its devices */
325 fibril_mutex_lock(&devices_list_mutex);
326 fibril_mutex_lock(&driver->devices_mutex);
327
328 while (!list_empty(&(driver->devices))) {
329 devmap_device_t *device = list_get_instance(driver->devices.next,
330 devmap_device_t, driver_devices);
331 devmap_device_unregister_core(device);
332 }
333
334 fibril_mutex_unlock(&driver->devices_mutex);
335 fibril_mutex_unlock(&devices_list_mutex);
336 fibril_mutex_unlock(&drivers_list_mutex);
337
338 /* free name and driver */
339 if (driver->name != NULL)
340 free(driver->name);
341
342 free(driver);
343
344 return EOK;
345}
346
347
348/** Process pending lookup requests */
349static void process_pending_lookup(void)
350{
351 link_t *cur;
352
353loop:
354 fibril_mutex_lock(&devices_list_mutex);
355 while (!pending_new_dev)
356 fibril_condvar_wait(&pending_cv, &devices_list_mutex);
357rescan:
358 for (cur = pending_req.next; cur != &pending_req; cur = cur->next) {
359 pending_req_t *pr = list_get_instance(cur, pending_req_t, link);
360
361 const devmap_device_t *dev = devmap_device_find_name(pr->name);
362 if (!dev)
363 continue;
364
365 ipc_answer_1(pr->callid, EOK, dev->handle);
366
367 free(pr->name);
368 list_remove(cur);
369 free(pr);
370
371 goto rescan;
372 }
373 pending_new_dev = false;
374 fibril_mutex_unlock(&devices_list_mutex);
375 goto loop;
376}
377
378
379/** Register instance of device
380 *
381 */
382static void devmap_device_register(ipc_callid_t iid, ipc_call_t *icall,
383 devmap_driver_t *driver)
384{
385 if (driver == NULL) {
386 ipc_answer_0(iid, EREFUSED);
387 return;
388 }
389
390 /* Create new device entry */
391 devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
392 if (device == NULL) {
393 ipc_answer_0(iid, ENOMEM);
394 return;
395 }
396
397 /* Get device name */
398 ipc_callid_t callid;
399 size_t size;
400 if (!ipc_data_write_receive(&callid, &size)) {
401 free(device);
402 ipc_answer_0(iid, EREFUSED);
403 return;
404 }
405
406 if (size > DEVMAP_NAME_MAXLEN) {
407 free(device);
408 ipc_answer_0(callid, EINVAL);
409 ipc_answer_0(iid, EREFUSED);
410 return;
411 }
412
413 /* +1 for terminating \0 */
414 device->name = (char *) malloc(size + 1);
415
416 if (device->name == NULL) {
417 free(device);
418 ipc_answer_0(callid, ENOMEM);
419 ipc_answer_0(iid, EREFUSED);
420 return;
421 }
422
423 ipc_data_write_finalize(callid, device->name, size);
424 device->name[size] = 0;
425
426 list_initialize(&(device->devices));
427 list_initialize(&(device->driver_devices));
428
429 fibril_mutex_lock(&devices_list_mutex);
430
431 /* Check that device with such name is not already registered */
432 if (NULL != devmap_device_find_name(device->name)) {
433 printf(NAME ": Device '%s' already registered\n", device->name);
434 fibril_mutex_unlock(&devices_list_mutex);
435 free(device->name);
436 free(device);
437 ipc_answer_0(iid, EEXISTS);
438 return;
439 }
440
441 /* Get unique device handle */
442 device->handle = devmap_create_handle();
443
444 device->driver = driver;
445
446 /* Insert device into list of all devices */
447 list_append(&device->devices, &devices_list);
448
449 /* Insert device into list of devices that belog to one driver */
450 fibril_mutex_lock(&device->driver->devices_mutex);
451
452 list_append(&device->driver_devices, &device->driver->devices);
453
454 fibril_mutex_unlock(&device->driver->devices_mutex);
455 pending_new_dev = true;
456 fibril_condvar_signal(&pending_cv);
457 fibril_mutex_unlock(&devices_list_mutex);
458
459 ipc_answer_1(iid, EOK, device->handle);
460}
461
462/**
463 *
464 */
465static int devmap_device_unregister(ipc_callid_t iid, ipc_call_t *icall,
466 devmap_driver_t *driver)
467{
468 /* TODO */
469 return EOK;
470}
471
472/** Connect client to the device.
473 *
474 * Find device driver owning requested device and forward
475 * the message to it.
476 *
477 */
478static void devmap_forward(ipc_callid_t callid, ipc_call_t *call)
479{
480 /*
481 * Get handle from request
482 */
483 dev_handle_t handle = IPC_GET_ARG2(*call);
484 devmap_device_t *dev = devmap_device_find_handle(handle);
485
486 if ((dev == NULL) || (dev->driver == NULL) || (dev->driver->phone == 0)) {
487 ipc_answer_0(callid, ENOENT);
488 return;
489 }
490
491 ipc_forward_fast(callid, dev->driver->phone, dev->handle,
492 IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
493}
494
495/** Find handle for device instance identified by name.
496 *
497 * In answer will be send EOK and device handle in arg1 or a error
498 * code from errno.h.
499 *
500 */
501static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall)
502{
503 /*
504 * Wait for incoming message with device name (but do not
505 * read the name itself until the buffer is allocated).
506 */
507 ipc_callid_t callid;
508 size_t size;
509 if (!ipc_data_write_receive(&callid, &size)) {
510 ipc_answer_0(callid, EREFUSED);
511 ipc_answer_0(iid, EREFUSED);
512 return;
513 }
514
515 if ((size < 1) || (size > DEVMAP_NAME_MAXLEN)) {
516 ipc_answer_0(callid, EINVAL);
517 ipc_answer_0(iid, EREFUSED);
518 return;
519 }
520
521 /*
522 * Allocate buffer for device name.
523 */
524 char *name = (char *) malloc(size + 1);
525 if (name == NULL) {
526 ipc_answer_0(callid, ENOMEM);
527 ipc_answer_0(iid, EREFUSED);
528 return;
529 }
530
531 /*
532 * Send confirmation to sender and get data into buffer.
533 */
534 ipcarg_t retval = ipc_data_write_finalize(callid, name, size);
535 if (retval != EOK) {
536 ipc_answer_0(iid, EREFUSED);
537 free(name);
538 return;
539 }
540 name[size] = '\0';
541
542 fibril_mutex_lock(&devices_list_mutex);
543
544 /*
545 * Find device name in linked list of known devices.
546 */
547 const devmap_device_t *dev = devmap_device_find_name(name);
548
549 /*
550 * Device was not found.
551 */
552 if (dev == NULL) {
553 if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
554 /* Blocking lookup, add to pending list */
555 pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t));
556 if (!pr) {
557 fibril_mutex_unlock(&devices_list_mutex);
558 ipc_answer_0(iid, ENOMEM);
559 free(name);
560 return;
561 }
562
563 pr->name = name;
564 pr->callid = iid;
565 list_append(&pr->link, &pending_req);
566 fibril_mutex_unlock(&devices_list_mutex);
567 return;
568 }
569
570 ipc_answer_0(iid, ENOENT);
571 free(name);
572 fibril_mutex_unlock(&devices_list_mutex);
573 return;
574 }
575 fibril_mutex_unlock(&devices_list_mutex);
576
577 ipc_answer_1(iid, EOK, dev->handle);
578 free(name);
579}
580
581/** Find name of device identified by id and send it to caller.
582 *
583 */
584static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall)
585{
586 const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
587
588 /*
589 * Device not found.
590 */
591 if (device == NULL) {
592 ipc_answer_0(iid, ENOENT);
593 return;
594 }
595
596 ipc_answer_0(iid, EOK);
597
598 size_t name_size = str_size(device->name);
599
600 /* FIXME:
601 * We have no channel from DEVMAP to client, therefore
602 * sending must be initiated by client.
603 *
604 * int rc = ipc_data_write_send(phone, device->name, name_size);
605 * if (rc != EOK) {
606 * async_wait_for(req, NULL);
607 * return rc;
608 * }
609 */
610
611 /* TODO: send name in response */
612}
613
614static void devmap_get_count(ipc_callid_t iid, ipc_call_t *icall)
615{
616 fibril_mutex_lock(&devices_list_mutex);
617 ipc_answer_1(iid, EOK, list_count(&devices_list));
618 fibril_mutex_unlock(&devices_list_mutex);
619}
620
621static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall)
622{
623 fibril_mutex_lock(&devices_list_mutex);
624
625 ipc_callid_t callid;
626 size_t size;
627 if (!ipc_data_read_receive(&callid, &size)) {
628 ipc_answer_0(callid, EREFUSED);
629 ipc_answer_0(iid, EREFUSED);
630 return;
631 }
632
633 if ((size % sizeof(dev_desc_t)) != 0) {
634 ipc_answer_0(callid, EINVAL);
635 ipc_answer_0(iid, EREFUSED);
636 return;
637 }
638
639 size_t count = size / sizeof(dev_desc_t);
640 dev_desc_t *desc = (dev_desc_t *) malloc(size);
641 if (desc == NULL) {
642 ipc_answer_0(callid, ENOMEM);
643 ipc_answer_0(iid, EREFUSED);
644 return;
645 }
646
647 size_t pos = 0;
648 link_t *item = devices_list.next;
649
650 while ((item != &devices_list) && (pos < count)) {
651 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
652
653 desc[pos].handle = device->handle;
654 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name);
655 pos++;
656 item = item->next;
657 }
658
659 ipcarg_t retval = ipc_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t));
660 if (retval != EOK) {
661 ipc_answer_0(iid, EREFUSED);
662 free(desc);
663 return;
664 }
665
666 free(desc);
667
668 fibril_mutex_unlock(&devices_list_mutex);
669
670 ipc_answer_1(iid, EOK, pos);
671}
672
673/** Initialize device mapper.
674 *
675 *
676 */
677static bool devmap_init(void)
678{
679 /* Create NULL device entry */
680 devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
681 if (device == NULL)
682 return false;
683
684 device->name = str_dup("null");
685 if (device->name == NULL) {
686 free(device);
687 return false;
688 }
689
690 list_initialize(&(device->devices));
691 list_initialize(&(device->driver_devices));
692
693 fibril_mutex_lock(&devices_list_mutex);
694
695 /* Get unique device handle */
696 device->handle = devmap_create_handle();
697 device->driver = NULL;
698
699 /* Insert device into list of all devices */
700 list_append(&device->devices, &devices_list);
701
702 fibril_mutex_unlock(&devices_list_mutex);
703
704 return true;
705}
706
707/** Handle connection with device driver.
708 *
709 */
710static void devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
711{
712 /* Accept connection */
713 ipc_answer_0(iid, EOK);
714
715 devmap_driver_t *driver = NULL;
716 devmap_driver_register(&driver);
717
718 if (NULL == driver)
719 return;
720
721 bool cont = true;
722 while (cont) {
723 ipc_call_t call;
724 ipc_callid_t callid = async_get_call(&call);
725
726 switch (IPC_GET_METHOD(call)) {
727 case IPC_M_PHONE_HUNGUP:
728 cont = false;
729 continue;
730 case DEVMAP_DRIVER_UNREGISTER:
731 if (NULL == driver)
732 ipc_answer_0(callid, ENOENT);
733 else
734 ipc_answer_0(callid, EOK);
735 break;
736 case DEVMAP_DEVICE_REGISTER:
737 /* Register one instance of device */
738 devmap_device_register(callid, &call, driver);
739 break;
740 case DEVMAP_DEVICE_UNREGISTER:
741 /* Remove instance of device identified by handler */
742 devmap_device_unregister(callid, &call, driver);
743 break;
744 case DEVMAP_DEVICE_GET_HANDLE:
745 devmap_get_handle(callid, &call);
746 break;
747 case DEVMAP_DEVICE_GET_NAME:
748 devmap_get_name(callid, &call);
749 break;
750 default:
751 if (!(callid & IPC_CALLID_NOTIFICATION))
752 ipc_answer_0(callid, ENOENT);
753 }
754 }
755
756 if (NULL != driver) {
757 /*
758 * Unregister the device driver and all its devices.
759 */
760 devmap_driver_unregister(driver);
761 driver = NULL;
762 }
763}
764
765/** Handle connection with device client.
766 *
767 */
768static void devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall)
769{
770 /* Accept connection */
771 ipc_answer_0(iid, EOK);
772
773 bool cont = true;
774 while (cont) {
775 ipc_call_t call;
776 ipc_callid_t callid = async_get_call(&call);
777
778 switch (IPC_GET_METHOD(call)) {
779 case IPC_M_PHONE_HUNGUP:
780 cont = false;
781 continue;
782 case DEVMAP_DEVICE_GET_HANDLE:
783 devmap_get_handle(callid, &call);
784 break;
785 case DEVMAP_DEVICE_GET_NAME:
786 devmap_get_name(callid, &call);
787 break;
788 case DEVMAP_DEVICE_GET_COUNT:
789 devmap_get_count(callid, &call);
790 break;
791 case DEVMAP_DEVICE_GET_DEVICES:
792 devmap_get_devices(callid, &call);
793 break;
794 default:
795 if (!(callid & IPC_CALLID_NOTIFICATION))
796 ipc_answer_0(callid, ENOENT);
797 }
798 }
799}
800
801/** Function for handling connections to devmap
802 *
803 */
804static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall)
805{
806 /* Select interface */
807 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
808 case DEVMAP_DRIVER:
809 devmap_connection_driver(iid, icall);
810 break;
811 case DEVMAP_CLIENT:
812 devmap_connection_client(iid, icall);
813 break;
814 case DEVMAP_CONNECT_TO_DEVICE:
815 /* Connect client to selected device */
816 devmap_forward(iid, icall);
817 break;
818 default:
819 /* No such interface */
820 ipc_answer_0(iid, ENOENT);
821 }
822}
823
824/**
825 *
826 */
827int main(int argc, char *argv[])
828{
829 printf(NAME ": HelenOS Device Mapper\n");
830
831 if (!devmap_init()) {
832 printf(NAME ": Error while initializing service\n");
833 return -1;
834 }
835
836 /* Set a handler of incomming connections */
837 async_set_client_connection(devmap_connection);
838
839 /* Create a fibril for handling pending device lookups */
840 fid_t fid = fibril_create(process_pending_lookup, NULL);
841 assert(fid);
842 fibril_add_ready(fid);
843
844 /* Register device mapper at naming service */
845 ipcarg_t phonead;
846 if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)
847 return -1;
848
849 printf(NAME ": Accepting connections\n");
850 async_manager();
851
852 /* Never reached */
853 return 0;
854}
855
856/**
857 * @}
858 */
Note: See TracBrowser for help on using the repository browser.