Subversion Repositories HelenOS

Rev

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

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