source: mainline/uspace/lib/libc/generic/devmap.c@ b6ee5b1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b6ee5b1 was 7fcb74c, checked in by Martin Decky <martin@…>, 16 years ago

add support for creating null devices on demand

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[1090b8c]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
[cb41a5e]38static int devmap_phone_driver = -1;
39static int devmap_phone_client = -1;
[1090b8c]40
41/** Get phone to device mapper task. */
[cb41a5e]42int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
[1090b8c]43{
[cb41a5e]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;
[1090b8c]71 }
[cb41a5e]72}
[1090b8c]73
[cb41a5e]74void 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;
91 }
[1090b8c]92}
93
94/** Register new driver with devmap. */
95int devmap_driver_register(const char *name, async_client_conn_t conn)
96{
[cb41a5e]97 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
98
99 if (phone < 0)
[1090b8c]100 return phone;
101
[e77994dd]102 async_serialize_start();
103
[cb41a5e]104 ipc_call_t answer;
105 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
106
107 ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
108
[1090b8c]109 if (retval != EOK) {
110 async_wait_for(req, NULL);
[e77994dd]111 async_serialize_end();
[1090b8c]112 return -1;
113 }
[cb41a5e]114
[1090b8c]115 async_set_client_connection(conn);
[cb41a5e]116
117 ipcarg_t callback_phonehash;
[1090b8c]118 ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
119 async_wait_for(req, &retval);
[cb41a5e]120
[e77994dd]121 async_serialize_end();
122
[cb41a5e]123 return retval;
[1090b8c]124}
125
[cb41a5e]126/** Register new device.
127 *
128 * @param name Device name.
129 * @param handle Output: Handle to the created instance of device.
130 *
131 */
132int devmap_device_register(const char *name, dev_handle_t *handle)
[1090b8c]133{
[cb41a5e]134 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
135
136 if (phone < 0)
137 return phone;
138
[e77994dd]139 async_serialize_start();
140
[1090b8c]141 ipc_call_t answer;
[cb41a5e]142 aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
143 &answer);
144
145 ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
146
147 if (retval != EOK) {
148 async_wait_for(req, NULL);
[e77994dd]149 async_serialize_end();
[cb41a5e]150 return retval;
151 }
152
153 async_wait_for(req, &retval);
154
[e77994dd]155 async_serialize_end();
156
[cb41a5e]157 if (retval != EOK) {
158 if (handle != NULL)
159 *handle = -1;
160 return retval;
161 }
162
163 if (handle != NULL)
164 *handle = (dev_handle_t) IPC_GET_ARG1(answer);
165
166 return retval;
167}
[1090b8c]168
[cb41a5e]169int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
170{
171 int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
172
[1090b8c]173 if (phone < 0)
174 return phone;
[cb41a5e]175
[e77994dd]176 async_serialize_start();
177
[cb41a5e]178 ipc_call_t answer;
179 aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
[1090b8c]180 &answer);
[cb41a5e]181
182 ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
183
[1090b8c]184 if (retval != EOK) {
185 async_wait_for(req, NULL);
[e77994dd]186 async_serialize_end();
[1090b8c]187 return retval;
188 }
[cb41a5e]189
[1090b8c]190 async_wait_for(req, &retval);
[cb41a5e]191
[e77994dd]192 async_serialize_end();
193
[1090b8c]194 if (retval != EOK) {
195 if (handle != NULL)
[62140db]196 *handle = (dev_handle_t) -1;
[1090b8c]197 return retval;
198 }
[cb41a5e]199
[1090b8c]200 if (handle != NULL)
[cb41a5e]201 *handle = (dev_handle_t) IPC_GET_ARG1(answer);
202
[1090b8c]203 return retval;
204}
205
206int devmap_device_connect(dev_handle_t handle, unsigned int flags)
207{
208 int phone;
[cb41a5e]209
[1090b8c]210 if (flags & IPC_FLAG_BLOCKING) {
211 phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
212 DEVMAP_CONNECT_TO_DEVICE, handle);
213 } else {
214 phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
215 DEVMAP_CONNECT_TO_DEVICE, handle);
216 }
[cb41a5e]217
[1090b8c]218 return phone;
219}
220
[7fcb74c]221int 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
236void 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
[cb41a5e]246ipcarg_t devmap_device_get_count(void)
[1090b8c]247{
[cb41a5e]248 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
249
250 if (phone < 0)
251 return 0;
252
253 ipcarg_t count;
[e77994dd]254 int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
[cb41a5e]255 if (retval != EOK)
256 return 0;
257
258 return count;
259}
[1090b8c]260
[cb41a5e]261ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
262{
263 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
264
265 if (phone < 0)
266 return 0;
267
[e77994dd]268 async_serialize_start();
269
[cb41a5e]270 ipc_call_t answer;
271 aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
272
273 ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
274
[1090b8c]275 if (retval != EOK) {
276 async_wait_for(req, NULL);
[e77994dd]277 async_serialize_end();
[cb41a5e]278 return 0;
[1090b8c]279 }
[cb41a5e]280
[1090b8c]281 async_wait_for(req, &retval);
[cb41a5e]282
[e77994dd]283 async_serialize_end();
284
[cb41a5e]285 if (retval != EOK)
286 return 0;
287
288 return IPC_GET_ARG1(answer);
[1090b8c]289}
Note: See TracBrowser for help on using the repository browser.