Subversion Repositories HelenOS

Rev

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

Rev 4420 Rev 4537
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();
-
 
103
   
102
    ipc_call_t answer;
104
    ipc_call_t answer;
103
    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);
104
   
106
   
105
    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);
106
   
108
   
107
    if (retval != EOK) {
109
    if (retval != EOK) {
108
        async_wait_for(req, NULL);
110
        async_wait_for(req, NULL);
-
 
111
        async_serialize_end();
109
        return -1;
112
        return -1;
110
    }
113
    }
111
   
114
   
112
    async_set_client_connection(conn);
115
    async_set_client_connection(conn);
113
   
116
   
114
    ipcarg_t callback_phonehash;
117
    ipcarg_t callback_phonehash;
115
    ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
118
    ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
116
    async_wait_for(req, &retval);
119
    async_wait_for(req, &retval);
117
   
120
   
-
 
121
    async_serialize_end();
-
 
122
   
118
    return retval;
123
    return retval;
119
}
124
}
120
 
125
 
121
/** Register new device.
126
/** Register new device.
122
 *
127
 *
123
 * @param name   Device name.
128
 * @param name   Device name.
124
 * @param handle Output: Handle to the created instance of device.
129
 * @param handle Output: Handle to the created instance of device.
125
 *
130
 *
126
 */
131
 */
127
int devmap_device_register(const char *name, dev_handle_t *handle)
132
int devmap_device_register(const char *name, dev_handle_t *handle)
128
{
133
{
129
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
134
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
130
   
135
   
131
    if (phone < 0)
136
    if (phone < 0)
132
        return phone;
137
        return phone;
133
   
138
   
-
 
139
    async_serialize_start();
-
 
140
   
134
    ipc_call_t answer;
141
    ipc_call_t answer;
135
    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,
136
        &answer);
143
        &answer);
137
   
144
   
138
    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);
139
   
146
   
140
    if (retval != EOK) {
147
    if (retval != EOK) {
141
        async_wait_for(req, NULL);
148
        async_wait_for(req, NULL);
-
 
149
        async_serialize_end();
142
        return retval;
150
        return retval;
143
    }
151
    }
144
   
152
   
145
    async_wait_for(req, &retval);
153
    async_wait_for(req, &retval);
146
   
154
   
-
 
155
    async_serialize_end();
-
 
156
   
147
    if (retval != EOK) {
157
    if (retval != EOK) {
148
        if (handle != NULL)
158
        if (handle != NULL)
149
            *handle = -1;
159
            *handle = -1;
150
        return retval;
160
        return retval;
151
    }
161
    }
152
   
162
   
153
    if (handle != NULL)
163
    if (handle != NULL)
154
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
164
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
155
   
165
   
156
    return retval;
166
    return retval;
157
}
167
}
158
 
168
 
159
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)
160
{
170
{
161
    int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
171
    int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
162
   
172
   
163
    if (phone < 0)
173
    if (phone < 0)
164
        return phone;
174
        return phone;
165
   
175
   
-
 
176
    async_serialize_start();
-
 
177
   
166
    ipc_call_t answer;
178
    ipc_call_t answer;
167
    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,
168
        &answer);
180
        &answer);
169
   
181
   
170
    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);
171
   
183
   
172
    if (retval != EOK) {
184
    if (retval != EOK) {
173
        async_wait_for(req, NULL);
185
        async_wait_for(req, NULL);
-
 
186
        async_serialize_end();
174
        return retval;
187
        return retval;
175
    }
188
    }
176
   
189
   
177
    async_wait_for(req, &retval);
190
    async_wait_for(req, &retval);
178
   
191
   
-
 
192
    async_serialize_end();
-
 
193
   
179
    if (retval != EOK) {
194
    if (retval != EOK) {
180
        if (handle != NULL)
195
        if (handle != NULL)
181
            *handle = -1;
196
            *handle = -1;
182
        return retval;
197
        return retval;
183
    }
198
    }
184
   
199
   
185
    if (handle != NULL)
200
    if (handle != NULL)
186
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
201
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
187
   
202
   
188
    return retval;
203
    return retval;
189
}
204
}
190
 
205
 
191
int devmap_device_connect(dev_handle_t handle, unsigned int flags)
206
int devmap_device_connect(dev_handle_t handle, unsigned int flags)
192
{
207
{
193
    int phone;
208
    int phone;
194
   
209
   
195
    if (flags & IPC_FLAG_BLOCKING) {
210
    if (flags & IPC_FLAG_BLOCKING) {
196
        phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
211
        phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
197
            DEVMAP_CONNECT_TO_DEVICE, handle);
212
            DEVMAP_CONNECT_TO_DEVICE, handle);
198
    } else {
213
    } else {
199
        phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
214
        phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
200
            DEVMAP_CONNECT_TO_DEVICE, handle);
215
            DEVMAP_CONNECT_TO_DEVICE, handle);
201
    }
216
    }
202
   
217
   
203
    return phone;
218
    return phone;
204
}
219
}
205
 
220
 
206
ipcarg_t devmap_device_get_count(void)
221
ipcarg_t devmap_device_get_count(void)
207
{
222
{
208
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
223
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
209
   
224
   
210
    if (phone < 0)
225
    if (phone < 0)
211
        return 0;
226
        return 0;
212
   
227
   
213
    ipcarg_t count;
228
    ipcarg_t count;
214
    int retval = ipc_call_sync_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
229
    int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
215
    if (retval != EOK)
230
    if (retval != EOK)
216
        return 0;
231
        return 0;
217
   
232
   
218
    return count;
233
    return count;
219
}
234
}
220
 
235
 
221
ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
236
ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
222
{
237
{
223
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
238
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
224
   
239
   
225
    if (phone < 0)
240
    if (phone < 0)
226
        return 0;
241
        return 0;
227
   
242
   
-
 
243
    async_serialize_start();
-
 
244
   
228
    ipc_call_t answer;
245
    ipc_call_t answer;
229
    aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
246
    aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
230
   
247
   
231
    ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
248
    ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
232
   
249
   
233
    if (retval != EOK) {
250
    if (retval != EOK) {
234
        async_wait_for(req, NULL);
251
        async_wait_for(req, NULL);
-
 
252
        async_serialize_end();
235
        return 0;
253
        return 0;
236
    }
254
    }
237
   
255
   
238
    async_wait_for(req, &retval);
256
    async_wait_for(req, &retval);
239
   
257
   
-
 
258
    async_serialize_end();
-
 
259
   
240
    if (retval != EOK)
260
    if (retval != EOK)
241
        return 0;
261
        return 0;
242
   
262
   
243
    return IPC_GET_ARG1(answer);
263
    return IPC_GET_ARG1(answer);
244
}
264
}
245
 
265