Subversion Repositories HelenOS

Rev

Rev 4401 | Rev 4474 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4401 svoboda 1
/*
2
 * Copyright (c) 2007 Josef Cejka
3
 * Copyright (c) 2009 Jiri Svoboda
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
12
 * - Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
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
16
 *   derived from this software without specific prior written permission.
17
 *
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
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
29
 
30
#include <string.h>
31
#include <ipc/ipc.h>
32
#include <ipc/services.h>
33
#include <ipc/devmap.h>
34
#include <devmap.h>
35
#include <async.h>
36
#include <errno.h>
37
 
4416 decky 38
static int devmap_phone_driver = -1;
39
static int devmap_phone_client = -1;
4401 svoboda 40
 
41
/** Get phone to device mapper task. */
4416 decky 42
int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
4401 svoboda 43
{
4416 decky 44
    switch (iface) {
45
    case DEVMAP_DRIVER:
46
        if (devmap_phone_driver >= 0)
47
            return devmap_phone_driver;
48
 
49
        if (flags & IPC_FLAG_BLOCKING)
50
            devmap_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
51
                SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
52
        else
53
            devmap_phone_driver = ipc_connect_me_to(PHONE_NS,
54
                SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
55
 
56
        return devmap_phone_driver;
57
    case DEVMAP_CLIENT:
58
        if (devmap_phone_client >= 0)
59
            return devmap_phone_client;
60
 
61
        if (flags & IPC_FLAG_BLOCKING)
62
            devmap_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
63
                SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
64
        else
65
            devmap_phone_client = ipc_connect_me_to(PHONE_NS,
66
                SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
67
 
68
        return devmap_phone_client;
69
    default:
70
        return -1;
71
    }
72
}
4401 svoboda 73
 
4416 decky 74
void devmap_hangup_phone(devmap_interface_t iface)
75
{
76
    switch (iface) {
77
    case DEVMAP_DRIVER:
78
        if (devmap_phone_driver >= 0) {
79
            ipc_hangup(devmap_phone_driver);
80
            devmap_phone_driver = -1;
81
        }
82
        break;
83
    case DEVMAP_CLIENT:
84
        if (devmap_phone_client >= 0) {
85
            ipc_hangup(devmap_phone_client);
86
            devmap_phone_client = -1;
87
        }
88
        break;
89
    default:
90
        break;
4401 svoboda 91
    }
92
}
93
 
94
/** Register new driver with devmap. */
95
int devmap_driver_register(const char *name, async_client_conn_t conn)
96
{
4416 decky 97
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
98
 
99
    if (phone < 0)
4401 svoboda 100
        return phone;
101
 
4416 decky 102
    ipc_call_t answer;
103
    aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
104
 
105
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
106
 
4401 svoboda 107
    if (retval != EOK) {
108
        async_wait_for(req, NULL);
109
        return -1;
110
    }
4416 decky 111
 
4401 svoboda 112
    async_set_client_connection(conn);
4416 decky 113
 
114
    ipcarg_t callback_phonehash;
4401 svoboda 115
    ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
116
    async_wait_for(req, &retval);
4416 decky 117
 
118
    return retval;
4401 svoboda 119
}
120
 
4416 decky 121
/** Register new device.
122
 *
123
 * @param name   Device name.
124
 * @param handle Output: Handle to the created instance of device.
125
 *
126
 */
127
int devmap_device_register(const char *name, dev_handle_t *handle)
4401 svoboda 128
{
4416 decky 129
    int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
130
 
131
    if (phone < 0)
132
        return phone;
133
 
4401 svoboda 134
    ipc_call_t answer;
4416 decky 135
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
136
        &answer);
137
 
138
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
139
 
140
    if (retval != EOK) {
141
        async_wait_for(req, NULL);
142
        return retval;
143
    }
144
 
145
    async_wait_for(req, &retval);
146
 
147
    if (retval != EOK) {
148
        if (handle != NULL)
149
            *handle = -1;
150
        return retval;
151
    }
152
 
153
    if (handle != NULL)
154
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
155
 
156
    return retval;
157
}
4401 svoboda 158
 
4416 decky 159
int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
160
{
161
    int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
162
 
4401 svoboda 163
    if (phone < 0)
164
        return phone;
4416 decky 165
 
166
    ipc_call_t answer;
167
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
4401 svoboda 168
        &answer);
4416 decky 169
 
170
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
171
 
4401 svoboda 172
    if (retval != EOK) {
173
        async_wait_for(req, NULL);
174
        return retval;
175
    }
4416 decky 176
 
4401 svoboda 177
    async_wait_for(req, &retval);
4416 decky 178
 
4401 svoboda 179
    if (retval != EOK) {
180
        if (handle != NULL)
181
            *handle = -1;
182
        return retval;
183
    }
4416 decky 184
 
4401 svoboda 185
    if (handle != NULL)
4416 decky 186
        *handle = (dev_handle_t) IPC_GET_ARG1(answer);
187
 
4401 svoboda 188
    return retval;
189
}
190
 
191
int devmap_device_connect(dev_handle_t handle, unsigned int flags)
192
{
193
    int phone;
4416 decky 194
 
4401 svoboda 195
    if (flags & IPC_FLAG_BLOCKING) {
196
        phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
197
            DEVMAP_CONNECT_TO_DEVICE, handle);
198
    } else {
199
        phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
200
            DEVMAP_CONNECT_TO_DEVICE, handle);
201
    }
4416 decky 202
 
4401 svoboda 203
    return phone;
204
}
205
 
4416 decky 206
ipcarg_t devmap_device_get_count(void)
4401 svoboda 207
{
4416 decky 208
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
209
 
210
    if (phone < 0)
211
        return 0;
212
 
213
    ipcarg_t count;
214
    int retval = ipc_call_sync_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
215
    if (retval != EOK)
216
        return 0;
217
 
218
    return count;
219
}
220
 
221
ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
222
{
223
    int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
224
 
225
    if (phone < 0)
226
        return 0;
227
 
4401 svoboda 228
    ipc_call_t answer;
4416 decky 229
    aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
230
 
231
    ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
232
 
4401 svoboda 233
    if (retval != EOK) {
234
        async_wait_for(req, NULL);
4416 decky 235
        return 0;
4401 svoboda 236
    }
4416 decky 237
 
4401 svoboda 238
    async_wait_for(req, &retval);
4416 decky 239
 
240
    if (retval != EOK)
241
        return 0;
242
 
243
    return IPC_GET_ARG1(answer);
4401 svoboda 244
}