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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a47d49f was 0da4e41, checked in by Jakub Jermar <jakub@…>, 16 years ago

ipc_data_*() and ipc_share_*(), respectively, should be renamed to
async_data_*() and async_share_*(), respectively, because these functions are
using the async framework.

  • Property mode set to 100644
File size: 6.8 KB
Line 
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
38static int devmap_phone_driver = -1;
39static int devmap_phone_client = -1;
40
41/** Get phone to device mapper task. */
42int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
43{
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}
73
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 }
92}
93
94/** Register new driver with devmap. */
95int devmap_driver_register(const char *name, async_client_conn_t conn)
96{
97 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
98
99 if (phone < 0)
100 return phone;
101
102 async_serialize_start();
103
104 ipc_call_t answer;
105 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
106
107 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
108
109 if (retval != EOK) {
110 async_wait_for(req, NULL);
111 async_serialize_end();
112 return -1;
113 }
114
115 async_set_client_connection(conn);
116
117 ipcarg_t callback_phonehash;
118 ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
119 async_wait_for(req, &retval);
120
121 async_serialize_end();
122
123 return retval;
124}
125
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)
133{
134 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
135
136 if (phone < 0)
137 return phone;
138
139 async_serialize_start();
140
141 ipc_call_t answer;
142 aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
143 &answer);
144
145 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
146
147 if (retval != EOK) {
148 async_wait_for(req, NULL);
149 async_serialize_end();
150 return retval;
151 }
152
153 async_wait_for(req, &retval);
154
155 async_serialize_end();
156
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}
168
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
173 if (phone < 0)
174 return phone;
175
176 async_serialize_start();
177
178 ipc_call_t answer;
179 aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
180 &answer);
181
182 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
183
184 if (retval != EOK) {
185 async_wait_for(req, NULL);
186 async_serialize_end();
187 return retval;
188 }
189
190 async_wait_for(req, &retval);
191
192 async_serialize_end();
193
194 if (retval != EOK) {
195 if (handle != NULL)
196 *handle = (dev_handle_t) -1;
197 return retval;
198 }
199
200 if (handle != NULL)
201 *handle = (dev_handle_t) IPC_GET_ARG1(answer);
202
203 return retval;
204}
205
206int devmap_device_connect(dev_handle_t handle, unsigned int flags)
207{
208 int phone;
209
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 }
217
218 return phone;
219}
220
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
246ipcarg_t devmap_device_get_count(void)
247{
248 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
249
250 if (phone < 0)
251 return 0;
252
253 ipcarg_t count;
254 int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
255 if (retval != EOK)
256 return 0;
257
258 return count;
259}
260
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
268 async_serialize_start();
269
270 ipc_call_t answer;
271 aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
272
273 ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t));
274
275 if (retval != EOK) {
276 async_wait_for(req, NULL);
277 async_serialize_end();
278 return 0;
279 }
280
281 async_wait_for(req, &retval);
282
283 async_serialize_end();
284
285 if (retval != EOK)
286 return 0;
287
288 return IPC_GET_ARG1(answer);
289}
Note: See TracBrowser for help on using the repository browser.