Subversion Repositories HelenOS

Rev

Rev 2678 | Rev 3424 | 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
     */
2676 jermar 205
    if (!ipc_data_write_receive(&callid, &name_size)) {
2619 jermar 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
     */
2678 jermar 236
    if (EOK != ipc_data_write_finalize(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
 
2637 cejka 272
    driver->phone = IPC_GET_ARG5(call);
2594 cejka 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 */
2676 jermar 371
    if (!ipc_data_write_receive(&callid, &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
 
2678 jermar 397
    ipc_data_write_finalize(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
static void devmap_forward(ipc_callid_t callid, ipc_call_t *call)
453
{
454
    devmap_device_t *dev;
455
    int handle;
456
 
457
    /*
458
     * Get handle from request
459
     */
2635 cejka 460
    handle = IPC_GET_ARG2(*call);
2594 cejka 461
    dev = devmap_device_find_handle(handle);
462
 
463
    if (NULL == dev) {
2619 jermar 464
        printf("DEVMAP: No registered device with handle %d.\n",
2598 jermar 465
            handle);
2619 jermar 466
        ipc_answer_0(callid, ENOENT);
2594 cejka 467
        return;
468
    }
469
 
2598 jermar 470
    ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle),
2635 cejka 471
        IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
2594 cejka 472
    return;
473
}
474
 
475
/** Find handle for device instance identified by name.
476
 * In answer will be send EOK and device handle in arg1 or a error
477
 * code from errno.h.
478
 */
479
static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall)
480
{
481
    char *name = NULL;
482
    size_t name_size;
483
    const devmap_device_t *dev;
484
    ipc_callid_t callid;
485
    ipcarg_t retval;
486
 
487
 
488
    /*
489
     * Wait for incoming message with device name (but do not
490
     * read the name itself until the buffer is allocated).
491
     */
2676 jermar 492
    if (!ipc_data_write_receive(&callid, &name_size)) {
2619 jermar 493
        ipc_answer_0(callid, EREFUSED);
494
        ipc_answer_0(iid, EREFUSED);
2594 cejka 495
        return;
496
    }
497
 
498
    if (name_size > DEVMAP_NAME_MAXLEN) {
2619 jermar 499
        ipc_answer_0(callid, EINVAL);
500
        ipc_answer_0(iid, EREFUSED);
2594 cejka 501
        return;
502
    }
503
 
504
    /*
505
     * Allocate buffer for device name.
506
     */
507
    if (NULL == (name = (char *)malloc(name_size))) {
2619 jermar 508
        ipc_answer_0(callid, ENOMEM);
509
        ipc_answer_0(iid, EREFUSED);
2594 cejka 510
        return;
511
    }  
512
 
513
    /*
514
     * Send confirmation to sender and get data into buffer.
515
     */
2678 jermar 516
    if (EOK != (retval = ipc_data_write_finalize(callid, name,
517
        name_size))) {
2619 jermar 518
        ipc_answer_0(iid, EREFUSED);
2594 cejka 519
        return;
520
    }
521
 
522
    /*
523
     * Find device name in linked list of known devices.
524
     */
525
    dev = devmap_device_find_name(name);
526
 
527
    /*
528
     * Device was not found.
529
     */
530
    if (NULL == dev) {
2619 jermar 531
        printf("DEVMAP: device %s has not been registered.\n", name);
532
        ipc_answer_0(iid, ENOENT);
2594 cejka 533
        return;
534
    }
535
 
2619 jermar 536
    printf("DEVMAP: device %s has handler %d.\n", name, dev->handle);
2594 cejka 537
 
2619 jermar 538
    ipc_answer_1(iid, EOK, dev->handle);
2594 cejka 539
 
540
    return;
541
}
542
 
543
/** Find name of device identified by id and send it to caller.
544
 *
545
 */
546
static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall)
547
{
548
    const devmap_device_t *device;
549
    size_t name_size;
550
 
551
    device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
552
 
553
    /*
554
     * Device not found.
555
     */
556
    if (NULL == device) {
2619 jermar 557
        ipc_answer_0(iid, ENOENT);
2594 cejka 558
        return;
559
    }  
560
 
2619 jermar 561
    ipc_answer_0(iid, EOK);
2594 cejka 562
 
563
    name_size = strlen(device->name);
564
 
565
 
566
/*  FIXME:
2619 jermar 567
    we have no channel from DEVMAP to client ->
2594 cejka 568
    sending must be initiated by client
569
 
2660 jermar 570
    int rc = ipc_data_write_send(phone, device->name, name_size);
2594 cejka 571
    if (rc != EOK) {
572
        async_wait_for(req, NULL);
573
        return rc;
574
    }
575
*/ 
576
    /* TODO: send name in response */
577
 
578
    return;
579
}
580
 
581
/** Handle connection with device driver.
582
 *
583
 */
2547 cejka 584
static void
2594 cejka 585
devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
2547 cejka 586
{
587
    ipc_callid_t callid;
588
    ipc_call_t call;
2555 cejka 589
    bool cont = true;
2594 cejka 590
    devmap_driver_t *driver = NULL;
2547 cejka 591
 
2619 jermar 592
    ipc_answer_0(iid, EOK);
2555 cejka 593
 
2594 cejka 594
    devmap_driver_register(&driver);
2547 cejka 595
 
2594 cejka 596
    if (NULL == driver) {
2619 jermar 597
        printf("DEVMAP: driver registration failed.\n");
2594 cejka 598
        return;
599
    }
600
 
2555 cejka 601
    while (cont) {
2547 cejka 602
        callid = async_get_call(&call);
603
 
604
        switch (IPC_GET_METHOD(call)) {
605
        case IPC_M_PHONE_HUNGUP:
2619 jermar 606
            printf("DEVMAP: connection hung up.\n");
2555 cejka 607
            cont = false;
608
            continue; /* Exit thread */
2594 cejka 609
        case DEVMAP_DRIVER_UNREGISTER:
2619 jermar 610
            printf("DEVMAP: unregister driver.\n");
2594 cejka 611
            if (NULL == driver) {
2619 jermar 612
                printf("DEVMAP: driver was not registered!\n");
613
                ipc_answer_0(callid, ENOENT);
2594 cejka 614
            } else {
2619 jermar 615
                ipc_answer_0(callid, EOK);
2555 cejka 616
            }
617
            break;
2594 cejka 618
        case DEVMAP_DEVICE_REGISTER:
619
            /* Register one instance of device */
620
            devmap_device_register(callid, &call, driver);
2555 cejka 621
            break;
2594 cejka 622
        case DEVMAP_DEVICE_UNREGISTER:
623
            /* Remove instance of device identified by handler */
624
            devmap_device_unregister(callid, &call, driver);
625
            break;
626
        case DEVMAP_DEVICE_GET_HANDLE:
627
            devmap_get_handle(callid, &call);
628
            break;
629
        case DEVMAP_DEVICE_GET_NAME:
630
            devmap_get_handle(callid, &call);
631
            break;
632
        default:
633
            if (!(callid & IPC_CALLID_NOTIFICATION)) {
2619 jermar 634
                ipc_answer_0(callid, ENOENT);
2594 cejka 635
            }
636
        }
637
    }
638
 
639
    if (NULL != driver) {
2619 jermar 640
        /*
641
         * Unregister the device driver and all its devices.
642
         */
2594 cejka 643
        devmap_driver_unregister(driver);
644
        driver = NULL;
645
    }
646
 
647
}
648
 
649
/** Handle connection with device client.
650
 *
651
 */
652
static void
653
devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall)
654
{
655
    ipc_callid_t callid;
656
    ipc_call_t call;
657
    bool cont = true;
658
 
2619 jermar 659
    ipc_answer_0(iid, EOK); /* Accept connection */
2594 cejka 660
 
661
    while (cont) {
662
        callid = async_get_call(&call);
663
 
664
        switch (IPC_GET_METHOD(call)) {
665
        case IPC_M_PHONE_HUNGUP:
2619 jermar 666
            printf("DEVMAP: connection hung up.\n");
2555 cejka 667
            cont = false;
2594 cejka 668
            continue; /* Exit thread */
669
 
670
        case DEVMAP_DEVICE_GET_HANDLE:
671
            devmap_get_handle(callid, &call);
672
 
2555 cejka 673
            break;
2594 cejka 674
        case DEVMAP_DEVICE_GET_NAME:
675
            /* TODO */
676
            devmap_get_name(callid, &call);
677
            break;
2547 cejka 678
        default:
2594 cejka 679
            if (!(callid & IPC_CALLID_NOTIFICATION)) {
2619 jermar 680
                ipc_answer_0(callid, ENOENT);
2594 cejka 681
            }
2547 cejka 682
        }
683
    }
2594 cejka 684
}
685
 
686
/** Function for handling connections to devmap
687
 *
688
 */
689
static void
690
devmap_connection(ipc_callid_t iid, ipc_call_t *icall)
691
{
692
 
2619 jermar 693
    printf("DEVMAP: new connection.\n");
2594 cejka 694
 
695
        /* Select interface */
696
    switch ((ipcarg_t)(IPC_GET_ARG1(*icall))) {
2598 jermar 697
    case DEVMAP_DRIVER:
698
        devmap_connection_driver(iid, icall);
699
        break;
700
    case DEVMAP_CLIENT:
701
        devmap_connection_client(iid, icall);
702
        break;
2635 cejka 703
    case DEVMAP_CONNECT_TO_DEVICE:
704
            /* Connect client to selected device */
705
        printf("DEVMAP: connect to device %d.\n",
706
            IPC_GET_ARG2(*icall));
707
        devmap_forward(iid, icall);
708
        break;
2598 jermar 709
    default:
2619 jermar 710
        ipc_answer_0(iid, ENOENT); /* No such interface */
711
        printf("DEVMAP: Unknown interface %u.\n",
2598 jermar 712
            (ipcarg_t)(IPC_GET_ARG1(*icall)));
2594 cejka 713
    }
714
 
715
    /* Cleanup */
716
 
2619 jermar 717
    printf("DEVMAP: connection closed.\n");
2555 cejka 718
    return;
2547 cejka 719
}
720
 
2594 cejka 721
/**
722
 *
723
 */
2547 cejka 724
int main(int argc, char *argv[])
725
{
726
    ipcarg_t phonead;
727
 
2619 jermar 728
    printf("DEVMAP: HelenOS device mapper.\n");
2547 cejka 729
 
730
    if (devmap_init() != 0) {
2619 jermar 731
        printf("Error while initializing DEVMAP service.\n");
2547 cejka 732
        return -1;
733
    }
734
 
735
        /* Set a handler of incomming connections */
2594 cejka 736
    async_set_client_connection(devmap_connection);
2547 cejka 737
 
2598 jermar 738
    /* Register device mapper at naming service */
2637 cejka 739
    if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)
2547 cejka 740
        return -1;
741
 
742
    async_manager();
743
    /* Never reached */
744
    return 0;
745
}
746
 
747
/**
748
 * @}
749
 */
750