Subversion Repositories HelenOS

Rev

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