Subversion Repositories HelenOS

Rev

Rev 4581 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4581 Rev 4718
1
/*
1
/*
2
 * Copyright (c) 2007 Josef Cejka
2
 * Copyright (c) 2007 Josef Cejka
3
 * Copyright (c) 2009 Jiri Svoboda
3
 * Copyright (c) 2009 Jiri Svoboda
4
 * All rights reserved.
4
 * All rights reserved.
5
 *
5
 *
6
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
8
 * are met:
8
 * are met:
9
 *
9
 *
10
 * - Redistributions of source code must retain the above copyright
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
11
 *   notice, this list of conditions and the following disclaimer.
12
 * - Redistributions in binary form must reproduce the above copyright
12
 * - Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
13
 *   notice, this list of conditions and the following disclaimer in the
14
 *   documentation and/or other materials provided with the distribution.
14
 *   documentation and/or other materials provided with the distribution.
15
 * - The name of the author may not be used to endorse or promote products
15
 * - The name of the author may not be used to endorse or promote products
16
 *   derived from this software without specific prior written permission.
16
 *   derived from this software without specific prior written permission.
17
 *
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
28
 */
29
 
29
 
30
#include <string.h>
30
#include <string.h>
31
#include <ipc/ipc.h>
31
#include <ipc/ipc.h>
32
#include <ipc/services.h>
32
#include <ipc/services.h>
33
#include <ipc/devmap.h>
33
#include <ipc/devmap.h>
34
#include <devmap.h>
34
#include <devmap.h>
35
#include <async.h>
35
#include <async.h>
36
#include <errno.h>
36
#include <errno.h>
37
 
37
 
38
static int devmap_phone_driver = -1;
38
static int devmap_phone_driver = -1;
39
static int devmap_phone_client = -1;
39
static int devmap_phone_client = -1;
40
 
40
 
41
/** Get phone to device mapper task. */
41
/** Get phone to device mapper task. */
42
int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
42
int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
43
{
43
{
44
    switch (iface) {
44
    switch (iface) {
45
    case DEVMAP_DRIVER:
45
    case DEVMAP_DRIVER:
46
        if (devmap_phone_driver >= 0)
46
        if (devmap_phone_driver >= 0)
47
            return devmap_phone_driver;
47
            return devmap_phone_driver;
48
       
48
       
49
        if (flags & IPC_FLAG_BLOCKING)
49
        if (flags & IPC_FLAG_BLOCKING)
50
            devmap_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
50
            devmap_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
51
                SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
51
                SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
52
        else
52
        else
53
            devmap_phone_driver = ipc_connect_me_to(PHONE_NS,
53
            devmap_phone_driver = ipc_connect_me_to(PHONE_NS,
54
                SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
54
                SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
55
       
55
       
56
        return devmap_phone_driver;
56
        return devmap_phone_driver;
57
    case DEVMAP_CLIENT:
57
    case DEVMAP_CLIENT:
58
        if (devmap_phone_client >= 0)
58
        if (devmap_phone_client >= 0)
59
            return devmap_phone_client;
59
            return devmap_phone_client;
60
       
60
       
61
        if (flags & IPC_FLAG_BLOCKING)
61
        if (flags & IPC_FLAG_BLOCKING)
62
            devmap_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
62
            devmap_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
63
                SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
63
                SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
64
        else
64
        else
65
            devmap_phone_client = ipc_connect_me_to(PHONE_NS,
65
            devmap_phone_client = ipc_connect_me_to(PHONE_NS,
66
                SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
66
                SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
67
       
67
       
68
        return devmap_phone_client;
68
        return devmap_phone_client;
69
    default:
69
    default:
70
        return -1;
70
        return -1;
71
    }
71
    }
72
}
72
}
73
 
73
 
74
void devmap_hangup_phone(devmap_interface_t iface)
74
void devmap_hangup_phone(devmap_interface_t iface)
75
{
75
{
76
    switch (iface) {
76
    switch (iface) {
77
    case DEVMAP_DRIVER:
77
    case DEVMAP_DRIVER:
78
        if (devmap_phone_driver >= 0) {
78
        if (devmap_phone_driver >= 0) {
79
            ipc_hangup(devmap_phone_driver);
79
            ipc_hangup(devmap_phone_driver);
80
            devmap_phone_driver = -1;
80
            devmap_phone_driver = -1;
81
        }
81
        }
82
        break;
82
        break;
83
    case DEVMAP_CLIENT:
83
    case DEVMAP_CLIENT:
84
        if (devmap_phone_client >= 0) {
84
        if (devmap_phone_client >= 0) {
85
            ipc_hangup(devmap_phone_client);
85
            ipc_hangup(devmap_phone_client);
86
            devmap_phone_client = -1;
86
            devmap_phone_client = -1;
87
        }
87
        }
88
        break;
88
        break;
89
    default:
89
    default:
90
        break;
90
        break;
91
    }
91
    }
92
}
92
}
93
 
93
 
94
/** Register new driver with devmap. */
94
/** Register new driver with devmap. */
95
int devmap_driver_register(const char *name, async_client_conn_t conn)
95
int devmap_driver_register(const char *name, async_client_conn_t conn)
96
{
96
{
97
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
97
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
98
   
98
   
99
    if (phone < 0)
99
    if (phone < 0)
100
        return phone;
100
        return phone;
101
   
101
   
102
    async_serialize_start();
102
    async_serialize_start();
103
   
103
   
104
    ipc_call_t answer;
104
    ipc_call_t answer;
105
    aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
105
    aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
106
   
106
   
107
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
107
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
108
   
108
   
109
    if (retval != EOK) {
109
    if (retval != EOK) {
110
        async_wait_for(req, NULL);
110
        async_wait_for(req, NULL);
111
        async_serialize_end();
111
        async_serialize_end();
112
        return -1;
112
        return -1;
113
    }
113
    }
114
   
114
   
115
    async_set_client_connection(conn);
115
    async_set_client_connection(conn);
116
   
116
   
117
    ipcarg_t callback_phonehash;
117
    ipcarg_t callback_phonehash;
118
    ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
118
    ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
119
    async_wait_for(req, &retval);
119
    async_wait_for(req, &retval);
120
   
120
   
121
    async_serialize_end();
121
    async_serialize_end();
122
   
122
   
123
    return retval;
123
    return retval;
124
}
124
}
125
 
125
 
126
/** Register new device.
126
/** Register new device.
127
 *
127
 *
128
 * @param name   Device name.
128
 * @param name   Device name.
129
 * @param handle Output: Handle to the created instance of device.
129
 * @param handle Output: Handle to the created instance of device.
130
 *
130
 *
131
 */
131
 */
132
int devmap_device_register(const char *name, dev_handle_t *handle)
132
int devmap_device_register(const char *name, dev_handle_t *handle)
133
{
133
{
134
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
134
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
135
   
135
   
136
    if (phone < 0)
136
    if (phone < 0)
137
        return phone;
137
        return phone;
138
   
138
   
139
    async_serialize_start();
139
    async_serialize_start();
140
   
140
   
141
    ipc_call_t answer;
141
    ipc_call_t answer;
142
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
142
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
143
        &answer);
143
        &answer);
144
   
144
   
145
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
145
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
146
   
146
   
147
    if (retval != EOK) {
147
    if (retval != EOK) {
148
        async_wait_for(req, NULL);
148
        async_wait_for(req, NULL);
149
        async_serialize_end();
149
        async_serialize_end();
150
        return retval;
150
        return retval;
151
    }
151
    }
152
   
152
   
153
    async_wait_for(req, &retval);
153
    async_wait_for(req, &retval);
154
   
154
   
155
    async_serialize_end();
155
    async_serialize_end();
156
   
156
   
157
    if (retval != EOK) {
157
    if (retval != EOK) {
158
        if (handle != NULL)
158
        if (handle != NULL)
159
            *handle = -1;
159
            *handle = -1;
160
        return retval;
160
        return retval;
161
    }
161
    }
162
   
162
   
163
    if (handle != NULL)
163
    if (handle != NULL)
164
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
164
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
165
   
165
   
166
    return retval;
166
    return retval;
167
}
167
}
168
 
168
 
169
int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
169
int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
170
{
170
{
171
    int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
171
    int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
172
   
172
   
173
    if (phone < 0)
173
    if (phone < 0)
174
        return phone;
174
        return phone;
175
   
175
   
176
    async_serialize_start();
176
    async_serialize_start();
177
   
177
   
178
    ipc_call_t answer;
178
    ipc_call_t answer;
179
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
179
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
180
        &answer);
180
        &answer);
181
   
181
   
182
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
182
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
183
   
183
   
184
    if (retval != EOK) {
184
    if (retval != EOK) {
185
        async_wait_for(req, NULL);
185
        async_wait_for(req, NULL);
186
        async_serialize_end();
186
        async_serialize_end();
187
        return retval;
187
        return retval;
188
    }
188
    }
189
   
189
   
190
    async_wait_for(req, &retval);
190
    async_wait_for(req, &retval);
191
   
191
   
192
    async_serialize_end();
192
    async_serialize_end();
193
   
193
   
194
    if (retval != EOK) {
194
    if (retval != EOK) {
195
        if (handle != NULL)
195
        if (handle != NULL)
196
            *handle = (dev_handle_t) -1;
196
            *handle = (dev_handle_t) -1;
197
        return retval;
197
        return retval;
198
    }
198
    }
199
   
199
   
200
    if (handle != NULL)
200
    if (handle != NULL)
201
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
201
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
202
   
202
   
203
    return retval;
203
    return retval;
204
}
204
}
205
 
205
 
206
int devmap_device_connect(dev_handle_t handle, unsigned int flags)
206
int devmap_device_connect(dev_handle_t handle, unsigned int flags)
207
{
207
{
208
    int phone;
208
    int phone;
209
   
209
   
210
    if (flags & IPC_FLAG_BLOCKING) {
210
    if (flags & IPC_FLAG_BLOCKING) {
211
        phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
211
        phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
212
            DEVMAP_CONNECT_TO_DEVICE, handle);
212
            DEVMAP_CONNECT_TO_DEVICE, handle);
213
    } else {
213
    } else {
214
        phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
214
        phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
215
            DEVMAP_CONNECT_TO_DEVICE, handle);
215
            DEVMAP_CONNECT_TO_DEVICE, handle);
216
    }
216
    }
217
   
217
   
218
    return phone;
218
    return phone;
219
}
219
}
220
 
220
 
-
 
221
int devmap_null_create(void)
-
 
222
{
-
 
223
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-
 
224
   
-
 
225
    if (phone < 0)
-
 
226
        return -1;
-
 
227
   
-
 
228
    ipcarg_t null_id;
-
 
229
    int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
-
 
230
    if (retval != EOK)
-
 
231
        return -1;
-
 
232
   
-
 
233
    return (int) null_id;
-
 
234
}
-
 
235
 
-
 
236
void devmap_null_destroy(int null_id)
-
 
237
{
-
 
238
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-
 
239
   
-
 
240
    if (phone < 0)
-
 
241
        return;
-
 
242
   
-
 
243
    async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
-
 
244
}
-
 
245
 
221
ipcarg_t devmap_device_get_count(void)
246
ipcarg_t devmap_device_get_count(void)
222
{
247
{
223
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
248
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
224
   
249
   
225
    if (phone < 0)
250
    if (phone < 0)
226
        return 0;
251
        return 0;
227
   
252
   
228
    ipcarg_t count;
253
    ipcarg_t count;
229
    int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
254
    int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
230
    if (retval != EOK)
255
    if (retval != EOK)
231
        return 0;
256
        return 0;
232
   
257
   
233
    return count;
258
    return count;
234
}
259
}
235
 
260
 
236
ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
261
ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
237
{
262
{
238
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
263
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
239
   
264
   
240
    if (phone < 0)
265
    if (phone < 0)
241
        return 0;
266
        return 0;
242
   
267
   
243
    async_serialize_start();
268
    async_serialize_start();
244
   
269
   
245
    ipc_call_t answer;
270
    ipc_call_t answer;
246
    aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
271
    aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
247
   
272
   
248
    ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
273
    ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
249
   
274
   
250
    if (retval != EOK) {
275
    if (retval != EOK) {
251
        async_wait_for(req, NULL);
276
        async_wait_for(req, NULL);
252
        async_serialize_end();
277
        async_serialize_end();
253
        return 0;
278
        return 0;
254
    }
279
    }
255
   
280
   
256
    async_wait_for(req, &retval);
281
    async_wait_for(req, &retval);
257
   
282
   
258
    async_serialize_end();
283
    async_serialize_end();
259
   
284
   
260
    if (retval != EOK)
285
    if (retval != EOK)
261
        return 0;
286
        return 0;
262
   
287
   
263
    return IPC_GET_ARG1(answer);
288
    return IPC_GET_ARG1(answer);
264
}
289
}
265
 
290