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

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

improve devmap interface
remove spared device

  • Property mode set to 100644
File size: 6.0 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 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
107 if (retval != EOK) {
108 async_wait_for(req, NULL);
109 return -1;
110 }
111
112 async_set_client_connection(conn);
113
114 ipcarg_t callback_phonehash;
115 ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
116 async_wait_for(req, &retval);
117
118 return retval;
119}
120
121/** Register new device.
122 *
123 * @param name Device name.
124 * @param handle Output: Handle to the created instance of device.
125 *
126 */
127int devmap_device_register(const char *name, dev_handle_t *handle)
128{
129 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
130
131 if (phone < 0)
132 return phone;
133
134 ipc_call_t answer;
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}
158
159int 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
163 if (phone < 0)
164 return phone;
165
166 ipc_call_t answer;
167 aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
168 &answer);
169
170 ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
171
172 if (retval != EOK) {
173 async_wait_for(req, NULL);
174 return retval;
175 }
176
177 async_wait_for(req, &retval);
178
179 if (retval != EOK) {
180 if (handle != NULL)
181 *handle = -1;
182 return retval;
183 }
184
185 if (handle != NULL)
186 *handle = (dev_handle_t) IPC_GET_ARG1(answer);
187
188 return retval;
189}
190
191int devmap_device_connect(dev_handle_t handle, unsigned int flags)
192{
193 int phone;
194
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 }
202
203 return phone;
204}
205
206ipcarg_t devmap_device_get_count(void)
207{
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
221ipcarg_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
228 ipc_call_t answer;
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
233 if (retval != EOK) {
234 async_wait_for(req, NULL);
235 return 0;
236 }
237
238 async_wait_for(req, &retval);
239
240 if (retval != EOK)
241 return 0;
242
243 return IPC_GET_ARG1(answer);
244}
Note: See TracBrowser for help on using the repository browser.