Subversion Repositories HelenOS

Rev

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

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