Subversion Repositories HelenOS

Rev

Rev 4264 | Rev 4458 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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