Subversion Repositories HelenOS

Rev

Rev 2555 | Rev 2598 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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