Subversion Repositories HelenOS

Rev

Rev 2678 | Rev 4009 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2547 cejka 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>
2555 cejka 43
#include <bool.h>
44
#include <futex.h>
2594 cejka 45
#include <stdlib.h>
46
#include <string.h>
3080 decky 47
#include <ipc/devmap.h>
2547 cejka 48
 
3080 decky 49
#define NAME "devmap"
2547 cejka 50
 
2555 cejka 51
 
2594 cejka 52
LIST_INITIALIZE(devices_list);
53
LIST_INITIALIZE(drivers_list);
2555 cejka 54
 
2594 cejka 55
/* order of locking:
56
 * drivers_list_futex
57
 * devices_list_futex
58
 * (devmap_driver_t *)->devices_futex
59
 * create_handle_futex
60
 **/
61
 
62
static atomic_t devices_list_futex = FUTEX_INITIALIZER;
63
static atomic_t drivers_list_futex = FUTEX_INITIALIZER;
64
static atomic_t create_handle_futex = FUTEX_INITIALIZER;
65
 
66
 
67
static int devmap_create_handle(void)
68
{
69
	static int last_handle = 0;
70
	int handle;
71
 
72
	/* TODO: allow reusing old handles after their unregistration
73
		and implement some version of LRU algorithm */
74
	/* FIXME: overflow */
75
	futex_down(&create_handle_futex);	
76
 
77
	last_handle += 1;
78
	handle = last_handle;
79
 
80
	futex_up(&create_handle_futex);	
81
 
82
	return handle;
83
}
84
 
85
 
2547 cejka 86
/** Initialize device mapper. 
87
 *
88
 *
89
 */
90
static int devmap_init()
91
{
2594 cejka 92
	/* TODO: */
2547 cejka 93
 
2555 cejka 94
	return EOK;
2547 cejka 95
}
96
 
2594 cejka 97
/** Find device with given name.
98
 *
99
 */
100
static devmap_device_t *devmap_device_find_name(const char *name)
2555 cejka 101
{
2594 cejka 102
	link_t *item;
103
	devmap_device_t *device = NULL;
104
 
105
	item = devices_list.next;
106
 
107
	while (item != &devices_list) {
108
 
109
		device = list_get_instance(item, devmap_device_t, devices);
110
		if (0 == strcmp(device->name, name)) {
111
			break;
112
		}
113
		item = item->next;
114
	}
115
 
3080 decky 116
	if (item == &devices_list)
2594 cejka 117
		return NULL;
118
 
119
	device = list_get_instance(item, devmap_device_t, devices);
120
	return device;
121
}
122
 
123
/** Find device with given handle.
124
 * @todo: use hash table
125
 */
126
static devmap_device_t *devmap_device_find_handle(int handle)
127
{
128
	link_t *item;
129
	devmap_device_t *device = NULL;
130
 
131
	futex_down(&devices_list_futex);
132
 
133
	item = (&devices_list)->next;
134
 
135
	while (item != &devices_list) {
136
 
137
		device = list_get_instance(item, devmap_device_t, devices);
138
		if (device->handle == handle) {
139
			break;
140
		}
141
		item = item->next;
142
	}
143
 
144
	if (item == &devices_list) {
145
		futex_up(&devices_list_futex);
146
		return NULL;
147
	}
148
 
149
	device = list_get_instance(item, devmap_device_t, devices);
150
 
151
	futex_up(&devices_list_futex);
152
 
153
	return device;
154
}
155
 
2598 jermar 156
/**
157
 * Unregister device and free it. It's assumed that driver's device list is
158
 * already locked.
2594 cejka 159
 */
160
static int devmap_device_unregister_core(devmap_device_t *device)
161
{
162
 
163
	list_remove(&(device->devices));
164
	list_remove(&(device->driver_devices));
165
 
166
	free(device->name);	
167
	free(device);
168
 
169
 
170
	return EOK;
171
}
172
 
2598 jermar 173
/**
174
 * Read info about new driver and add it into linked list of registered
175
 * drivers.
2594 cejka 176
 */
177
static void devmap_driver_register(devmap_driver_t **odriver)
178
{
179
	size_t name_size;
2555 cejka 180
	ipc_callid_t callid;
181
	ipc_call_t call;
2594 cejka 182
	devmap_driver_t *driver;
183
	ipc_callid_t iid;
184
	ipc_call_t icall;
185
 
186
	*odriver = NULL;
2555 cejka 187
 
2594 cejka 188
	iid = async_get_call(&icall);
189
 
190
	if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) {
2619 jermar 191
		ipc_answer_0(iid, EREFUSED);
2594 cejka 192
		return;
193
	} 
194
 
2598 jermar 195
	if (NULL ==
196
	    (driver = (devmap_driver_t *)malloc(sizeof(devmap_driver_t)))) {
2619 jermar 197
		ipc_answer_0(iid, ENOMEM);
2594 cejka 198
		return;
2555 cejka 199
	}
2547 cejka 200
 
2594 cejka 201
	/* 
202
	 * Get driver name
203
	 */
2676 jermar 204
	if (!ipc_data_write_receive(&callid, &name_size)) {
2594 cejka 205
		free(driver);
2619 jermar 206
		ipc_answer_0(callid, EREFUSED);
207
		ipc_answer_0(iid, EREFUSED);
2594 cejka 208
		return;
2555 cejka 209
	}
2594 cejka 210
 
211
	if (name_size > DEVMAP_NAME_MAXLEN) {
212
		free(driver);
2619 jermar 213
		ipc_answer_0(callid, EINVAL);
214
		ipc_answer_0(iid, EREFUSED);
2594 cejka 215
		return;
216
	}
217
 
218
	/*
219
	 * Allocate buffer for device name.
220
	 */
221
	if (NULL == (driver->name = (char *)malloc(name_size + 1))) {
222
		free(driver);
2619 jermar 223
		ipc_answer_0(callid, ENOMEM);
224
		ipc_answer_0(iid, EREFUSED);
2594 cejka 225
		return;
226
	}	
227
 
228
	/*
229
	 * Send confirmation to sender and get data into buffer.
230
	 */
2678 jermar 231
	if (EOK != ipc_data_write_finalize(callid, driver->name, name_size)) {
2594 cejka 232
		free(driver->name);
233
		free(driver);
2619 jermar 234
		ipc_answer_0(iid, EREFUSED);
2594 cejka 235
		return;
236
	}
237
 
238
	driver->name[name_size] = 0;
239
 
240
	/* Initialize futex for list of devices owned by this driver */
2598 jermar 241
	futex_initialize(&(driver->devices_futex), 1);
2594 cejka 242
 
243
	/* 
244
	 * Initialize list of asociated devices
2619 jermar 245
	 */
2594 cejka 246
	list_initialize(&(driver->devices));
247
 
248
	/* 
249
	 * Create connection to the driver 
250
	 */
251
	callid = async_get_call(&call);
252
 
253
	if (IPC_M_CONNECT_TO_ME != IPC_GET_METHOD(call)) {
2619 jermar 254
		ipc_answer_0(callid, ENOTSUP);
2594 cejka 255
 
256
		free(driver->name);
257
		free(driver);
2619 jermar 258
		ipc_answer_0(iid, ENOTSUP);
2594 cejka 259
		return;
260
	}
261
 
2637 cejka 262
	driver->phone = IPC_GET_ARG5(call);
2594 cejka 263
 
2619 jermar 264
	ipc_answer_0(callid, EOK);
2594 cejka 265
 
266
	list_initialize(&(driver->drivers));
267
 
268
	futex_down(&drivers_list_futex);	
269
 
2598 jermar 270
	/* TODO:
271
	 * check that no driver with name equal to driver->name is registered
272
	 */
2594 cejka 273
 
274
	/* 
275
	 * Insert new driver into list of registered drivers
276
	 */
277
	list_append(&(driver->drivers), &drivers_list);
278
	futex_up(&drivers_list_futex);	
279
 
2619 jermar 280
	ipc_answer_0(iid, EOK);
2594 cejka 281
 
282
	*odriver = driver;
2555 cejka 283
}
284
 
2619 jermar 285
/** Unregister device driver, unregister all its devices and free driver
286
 * structure.
2594 cejka 287
 */
288
static int devmap_driver_unregister(devmap_driver_t *driver)
2555 cejka 289
{
2594 cejka 290
	devmap_device_t *device;
291
 
3080 decky 292
	if (NULL == driver)
2594 cejka 293
		return EEXISTS;
3080 decky 294
 
2594 cejka 295
	futex_down(&drivers_list_futex);	
296
 
297
	ipc_hangup(driver->phone);
298
 
299
	/* remove it from list of drivers */
300
	list_remove(&(driver->drivers));
301
 
302
	/* unregister all its devices */
303
 
304
	futex_down(&devices_list_futex);	
305
	futex_down(&(driver->devices_futex));
306
 
307
	while (!list_empty(&(driver->devices))) {
2598 jermar 308
		device = list_get_instance(driver->devices.next,
309
		    devmap_device_t, driver_devices);
2594 cejka 310
		devmap_device_unregister_core(device);
311
	}
312
 
313
	futex_up(&(driver->devices_futex));
314
	futex_up(&devices_list_futex);	
315
	futex_up(&drivers_list_futex);	
316
 
317
	/* free name and driver */
318
	if (NULL != driver->name) {
319
		free(driver->name);
320
	}
321
 
322
	free(driver);
323
 
2555 cejka 324
	return EOK;
325
}
326
 
2594 cejka 327
 
328
/** Register instance of device
329
 *
330
 */
331
static void devmap_device_register(ipc_callid_t iid, ipc_call_t *icall,
2619 jermar 332
    devmap_driver_t *driver)
2555 cejka 333
{
2594 cejka 334
	ipc_callid_t callid;
335
	size_t size;
336
	devmap_device_t *device;
2555 cejka 337
 
2594 cejka 338
	if (NULL == driver) {
2619 jermar 339
		ipc_answer_0(iid, EREFUSED);
2594 cejka 340
		return;
341
	}
342
 
343
	/* Create new device entry */
2598 jermar 344
	if (NULL ==
3080 decky 345
	    (device = (devmap_device_t *) malloc(sizeof(devmap_device_t)))) {
2619 jermar 346
		ipc_answer_0(iid, ENOMEM);
2594 cejka 347
		return;
348
	}
349
 
350
	/* Get device name */
2676 jermar 351
	if (!ipc_data_write_receive(&callid, &size)) {
2594 cejka 352
		free(device);
2619 jermar 353
		ipc_answer_0(iid, EREFUSED);
2594 cejka 354
		return;
355
	}
2555 cejka 356
 
2594 cejka 357
	if (size > DEVMAP_NAME_MAXLEN) {
358
		free(device);
2619 jermar 359
		ipc_answer_0(callid, EINVAL);
360
		ipc_answer_0(iid, EREFUSED);
2594 cejka 361
		return;
362
	}
3080 decky 363
 
364
	/* +1 for terminating \0 */
365
	device->name = (char *) malloc(size + 1);
2555 cejka 366
 
2594 cejka 367
	if (NULL == device->name) {
368
		free(device);
2619 jermar 369
		ipc_answer_0(callid, ENOMEM);
370
		ipc_answer_0(iid, EREFUSED);
2594 cejka 371
		return;
2555 cejka 372
	}
2594 cejka 373
 
2678 jermar 374
	ipc_data_write_finalize(callid, device->name, size);
2594 cejka 375
	device->name[size] = 0;
2555 cejka 376
 
2594 cejka 377
	list_initialize(&(device->devices));
378
	list_initialize(&(device->driver_devices));
379
 
380
	futex_down(&devices_list_futex);	
381
 
382
	/* Check that device with such name is not already registered */
383
	if (NULL != devmap_device_find_name(device->name)) {
3080 decky 384
		printf(NAME ": Device '%s' already registered\n", device->name);
2594 cejka 385
		futex_up(&devices_list_futex);	
386
		free(device->name);
387
		free(device);
2619 jermar 388
		ipc_answer_0(iid, EEXISTS);
2594 cejka 389
		return;
2555 cejka 390
	}
391
 
2594 cejka 392
	/* Get unique device handle */
393
	device->handle = devmap_create_handle(); 
2555 cejka 394
 
2594 cejka 395
	device->driver = driver;
2555 cejka 396
 
2594 cejka 397
	/* Insert device into list of all devices  */
2619 jermar 398
	list_append(&device->devices, &devices_list);
2594 cejka 399
 
400
	/* Insert device into list of devices that belog to one driver */
2619 jermar 401
	futex_down(&device->driver->devices_futex);	
2594 cejka 402
 
2619 jermar 403
	list_append(&device->driver_devices, &device->driver->devices);
2594 cejka 404
 
2619 jermar 405
	futex_up(&device->driver->devices_futex);	
2594 cejka 406
	futex_up(&devices_list_futex);	
407
 
2619 jermar 408
	ipc_answer_1(iid, EOK, device->handle);
2555 cejka 409
}
410
 
2594 cejka 411
/**
412
 *
413
 */
414
static int devmap_device_unregister(ipc_callid_t iid, ipc_call_t *icall, 
2619 jermar 415
    devmap_driver_t *driver)
2555 cejka 416
{
2594 cejka 417
	/* TODO */
418
 
2555 cejka 419
	return EOK;
420
}
421
 
2594 cejka 422
/** Connect client to the device.
423
 * Find device driver owning requested device and forward
424
 * the message to it.
2547 cejka 425
 */
2594 cejka 426
static void devmap_forward(ipc_callid_t callid, ipc_call_t *call)
427
{
428
	devmap_device_t *dev;
429
	int handle;
430
 
431
	/*
432
	 * Get handle from request
433
	 */
2635 cejka 434
	handle = IPC_GET_ARG2(*call);
2594 cejka 435
	dev = devmap_device_find_handle(handle);
436
 
437
	if (NULL == dev) {
2619 jermar 438
		ipc_answer_0(callid, ENOENT);
2594 cejka 439
		return;
440
	} 
441
 
2598 jermar 442
	ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle),
2635 cejka 443
	    IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
2594 cejka 444
}
445
 
446
/** Find handle for device instance identified by name.
447
 * In answer will be send EOK and device handle in arg1 or a error
448
 * code from errno.h. 
449
 */
450
static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall)
451
{
452
	char *name = NULL;
453
	size_t name_size;
454
	const devmap_device_t *dev;
455
	ipc_callid_t callid;
456
	ipcarg_t retval;
457
 
458
	/* 
459
	 * Wait for incoming message with device name (but do not
460
	 * read the name itself until the buffer is allocated).
461
	 */
2676 jermar 462
	if (!ipc_data_write_receive(&callid, &name_size)) {
2619 jermar 463
		ipc_answer_0(callid, EREFUSED);
464
		ipc_answer_0(iid, EREFUSED);
2594 cejka 465
		return;
466
	}
467
 
468
	if (name_size > DEVMAP_NAME_MAXLEN) {
2619 jermar 469
		ipc_answer_0(callid, EINVAL);
470
		ipc_answer_0(iid, EREFUSED);
2594 cejka 471
		return;
472
	}
473
 
474
	/*
475
	 * Allocate buffer for device name.
476
	 */
477
	if (NULL == (name = (char *)malloc(name_size))) {
2619 jermar 478
		ipc_answer_0(callid, ENOMEM);
479
		ipc_answer_0(iid, EREFUSED);
2594 cejka 480
		return;
481
	}	
482
 
483
	/*
484
	 * Send confirmation to sender and get data into buffer.
485
	 */
2678 jermar 486
	if (EOK != (retval = ipc_data_write_finalize(callid, name,
487
	    name_size))) {
2619 jermar 488
		ipc_answer_0(iid, EREFUSED);
2594 cejka 489
		return;
490
	}
491
 
492
	/*
493
	 * Find device name in linked list of known devices.
494
	 */
495
	dev = devmap_device_find_name(name);
496
 
497
	/*
498
	 * Device was not found.
499
	 */
500
	if (NULL == dev) {
2619 jermar 501
		ipc_answer_0(iid, ENOENT);
2594 cejka 502
		return;
503
	}
504
 
2619 jermar 505
	ipc_answer_1(iid, EOK, dev->handle);
2594 cejka 506
}
507
 
508
/** Find name of device identified by id and send it to caller. 
509
 *
510
 */
511
static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall) 
512
{
513
	const devmap_device_t *device;
514
	size_t name_size;
515
 
516
	device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
517
 
518
	/*
519
	 * Device not found.
520
	 */
521
	if (NULL == device) {
2619 jermar 522
		ipc_answer_0(iid, ENOENT);
2594 cejka 523
		return;
524
	}	
525
 
2619 jermar 526
	ipc_answer_0(iid, EOK);
2594 cejka 527
 
528
	name_size = strlen(device->name);
529
 
530
 
531
/*	FIXME:
2619 jermar 532
	we have no channel from DEVMAP to client -> 
2594 cejka 533
	sending must be initiated by client
534
 
2660 jermar 535
	int rc = ipc_data_write_send(phone, device->name, name_size); 
2594 cejka 536
	if (rc != EOK) {
537
		async_wait_for(req, NULL);
538
		return rc;
539
	}
540
*/	
541
	/* TODO: send name in response */
542
}
543
 
544
/** Handle connection with device driver.
545
 *
546
 */
3080 decky 547
static void devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
2547 cejka 548
{
549
	ipc_callid_t callid;
550
	ipc_call_t call;
2555 cejka 551
	bool cont = true;
2594 cejka 552
	devmap_driver_t *driver = NULL; 
2547 cejka 553
 
2619 jermar 554
	ipc_answer_0(iid, EOK); 
2555 cejka 555
 
2594 cejka 556
	devmap_driver_register(&driver);
2547 cejka 557
 
3080 decky 558
	if (NULL == driver)
2594 cejka 559
		return;
560
 
2555 cejka 561
	while (cont) {
2547 cejka 562
		callid = async_get_call(&call);
563
 
564
 		switch (IPC_GET_METHOD(call)) {
565
		case IPC_M_PHONE_HUNGUP:
2555 cejka 566
			cont = false;
567
			continue; /* Exit thread */
2594 cejka 568
		case DEVMAP_DRIVER_UNREGISTER:
569
			if (NULL == driver) {
2619 jermar 570
				ipc_answer_0(callid, ENOENT);
2594 cejka 571
			} else {
2619 jermar 572
				ipc_answer_0(callid, EOK);
2555 cejka 573
			}
574
			break;
2594 cejka 575
		case DEVMAP_DEVICE_REGISTER:
576
			/* Register one instance of device */
577
			devmap_device_register(callid, &call, driver);
2555 cejka 578
			break;
2594 cejka 579
		case DEVMAP_DEVICE_UNREGISTER:
580
			/* Remove instance of device identified by handler */
581
			devmap_device_unregister(callid, &call, driver);
582
			break;
583
		case DEVMAP_DEVICE_GET_HANDLE:
584
			devmap_get_handle(callid, &call);
585
			break;
586
		case DEVMAP_DEVICE_GET_NAME:
587
			devmap_get_handle(callid, &call);
588
			break;
589
		default:
590
			if (!(callid & IPC_CALLID_NOTIFICATION)) {
2619 jermar 591
				ipc_answer_0(callid, ENOENT);
2594 cejka 592
			}
593
		}
594
	}
595
 
596
	if (NULL != driver) {
2619 jermar 597
		/* 
598
		 * Unregister the device driver and all its devices.
599
		 */
2594 cejka 600
		devmap_driver_unregister(driver);
601
		driver = NULL;
602
	}
603
 
604
}
605
 
606
/** Handle connection with device client.
607
 *
608
 */
3080 decky 609
static void devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall)
2594 cejka 610
{
611
	ipc_callid_t callid;
612
	ipc_call_t call;
613
	bool cont = true;
614
 
2619 jermar 615
	ipc_answer_0(iid, EOK); /* Accept connection */
2594 cejka 616
 
617
	while (cont) {
618
		callid = async_get_call(&call);
619
 
620
 		switch (IPC_GET_METHOD(call)) {
621
		case IPC_M_PHONE_HUNGUP:
2555 cejka 622
			cont = false;
2594 cejka 623
			continue; /* Exit thread */
624
 
625
		case DEVMAP_DEVICE_GET_HANDLE:
626
 			devmap_get_handle(callid, &call);
627
 
2555 cejka 628
			break;
2594 cejka 629
		case DEVMAP_DEVICE_GET_NAME:
630
			/* TODO */
631
			devmap_get_name(callid, &call);
632
			break;
2547 cejka 633
		default:
2594 cejka 634
			if (!(callid & IPC_CALLID_NOTIFICATION)) {
2619 jermar 635
				ipc_answer_0(callid, ENOENT);
2594 cejka 636
			}
2547 cejka 637
		}
638
	}
2594 cejka 639
}
640
 
641
/** Function for handling connections to devmap 
642
 *
643
 */
3080 decky 644
static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall)
2594 cejka 645
{
3080 decky 646
	/* Select interface */
647
	switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
2598 jermar 648
	case DEVMAP_DRIVER:
649
		devmap_connection_driver(iid, icall);
650
		break;
651
	case DEVMAP_CLIENT:
652
		devmap_connection_client(iid, icall);
653
		break;
2635 cejka 654
	case DEVMAP_CONNECT_TO_DEVICE:
3080 decky 655
		/* Connect client to selected device */
2635 cejka 656
		devmap_forward(iid, icall);
657
		break;
2598 jermar 658
	default:
2619 jermar 659
		ipc_answer_0(iid, ENOENT); /* No such interface */
2594 cejka 660
	}
661
 
662
	/* Cleanup */
2547 cejka 663
}
664
 
2594 cejka 665
/**
666
 *
667
 */
2547 cejka 668
int main(int argc, char *argv[])
669
{
3080 decky 670
	printf(NAME ": HelenOS Device Mapper\n");
671
 
2547 cejka 672
	ipcarg_t phonead;
673
 
674
	if (devmap_init() != 0) {
3080 decky 675
		printf(NAME ": Error while initializing service\n");
2547 cejka 676
		return -1;
677
	}
3080 decky 678
 
679
	/* Set a handler of incomming connections */
2594 cejka 680
	async_set_client_connection(devmap_connection);
2547 cejka 681
 
2598 jermar 682
	/* Register device mapper at naming service */
2637 cejka 683
	if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) 
2547 cejka 684
		return -1;
685
 
3080 decky 686
	printf(NAME ": Accepting connections\n");
2547 cejka 687
	async_manager();
688
	/* Never reached */
689
	return 0;
690
}
691
 
692
/** 
693
 * @}
694
 */