source: mainline/uspace/lib/c/generic/bd_srv.c@ 984a9ba

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

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Block device server stub
35 */
36#include <errno.h>
37#include <ipc/bd.h>
38#include <macros.h>
39#include <stdlib.h>
40#include <stddef.h>
41#include <stdint.h>
42
43#include <bd_srv.h>
44
45static void bd_read_blocks_srv(bd_srv_t *srv, ipc_call_t *call)
46{
47 aoff64_t ba;
48 size_t cnt;
49 void *buf;
50 size_t size;
51 errno_t rc;
52
53 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
54 cnt = IPC_GET_ARG3(*call);
55
56 ipc_call_t rcall;
57 if (!async_data_read_receive(&rcall, &size)) {
58 async_answer_0(call, EINVAL);
59 return;
60 }
61
62 buf = malloc(size);
63 if (buf == NULL) {
64 async_answer_0(&rcall, ENOMEM);
65 async_answer_0(call, ENOMEM);
66 return;
67 }
68
69 if (srv->srvs->ops->read_blocks == NULL) {
70 async_answer_0(&rcall, ENOTSUP);
71 async_answer_0(call, ENOTSUP);
72 free(buf);
73 return;
74 }
75
76 rc = srv->srvs->ops->read_blocks(srv, ba, cnt, buf, size);
77 if (rc != EOK) {
78 async_answer_0(&rcall, ENOMEM);
79 async_answer_0(call, ENOMEM);
80 free(buf);
81 return;
82 }
83
84 async_data_read_finalize(&rcall, buf, size);
85
86 free(buf);
87 async_answer_0(call, EOK);
88}
89
90static void bd_read_toc_srv(bd_srv_t *srv, ipc_call_t *call)
91{
92 uint8_t session;
93 void *buf;
94 size_t size;
95 errno_t rc;
96
97 session = IPC_GET_ARG1(*call);
98
99 ipc_call_t rcall;
100 if (!async_data_read_receive(&rcall, &size)) {
101 async_answer_0(call, EINVAL);
102 return;
103 }
104
105 buf = malloc(size);
106 if (buf == NULL) {
107 async_answer_0(&rcall, ENOMEM);
108 async_answer_0(call, ENOMEM);
109 return;
110 }
111
112 if (srv->srvs->ops->read_toc == NULL) {
113 async_answer_0(&rcall, ENOTSUP);
114 async_answer_0(call, ENOTSUP);
115 free(buf);
116 return;
117 }
118
119 rc = srv->srvs->ops->read_toc(srv, session, buf, size);
120 if (rc != EOK) {
121 async_answer_0(&rcall, ENOMEM);
122 async_answer_0(call, ENOMEM);
123 free(buf);
124 return;
125 }
126
127 async_data_read_finalize(&rcall, buf, size);
128
129 free(buf);
130 async_answer_0(call, EOK);
131}
132
133static void bd_sync_cache_srv(bd_srv_t *srv, ipc_call_t *call)
134{
135 aoff64_t ba;
136 size_t cnt;
137 errno_t rc;
138
139 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
140 cnt = IPC_GET_ARG3(*call);
141
142 if (srv->srvs->ops->sync_cache == NULL) {
143 async_answer_0(call, ENOTSUP);
144 return;
145 }
146
147 rc = srv->srvs->ops->sync_cache(srv, ba, cnt);
148 async_answer_0(call, rc);
149}
150
151static void bd_write_blocks_srv(bd_srv_t *srv, ipc_call_t *call)
152{
153 aoff64_t ba;
154 size_t cnt;
155 void *data;
156 size_t size;
157 errno_t rc;
158
159 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
160 cnt = IPC_GET_ARG3(*call);
161
162 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
163 if (rc != EOK) {
164 async_answer_0(call, rc);
165 return;
166 }
167
168 if (srv->srvs->ops->write_blocks == NULL) {
169 async_answer_0(call, ENOTSUP);
170 return;
171 }
172
173 rc = srv->srvs->ops->write_blocks(srv, ba, cnt, data, size);
174 free(data);
175 async_answer_0(call, rc);
176}
177
178static void bd_get_block_size_srv(bd_srv_t *srv, ipc_call_t *call)
179{
180 errno_t rc;
181 size_t block_size;
182
183 if (srv->srvs->ops->get_block_size == NULL) {
184 async_answer_0(call, ENOTSUP);
185 return;
186 }
187
188 rc = srv->srvs->ops->get_block_size(srv, &block_size);
189 async_answer_1(call, rc, block_size);
190}
191
192static void bd_get_num_blocks_srv(bd_srv_t *srv, ipc_call_t *call)
193{
194 errno_t rc;
195 aoff64_t num_blocks;
196
197 if (srv->srvs->ops->get_num_blocks == NULL) {
198 async_answer_0(call, ENOTSUP);
199 return;
200 }
201
202 rc = srv->srvs->ops->get_num_blocks(srv, &num_blocks);
203 async_answer_2(call, rc, LOWER32(num_blocks), UPPER32(num_blocks));
204}
205
206static bd_srv_t *bd_srv_create(bd_srvs_t *srvs)
207{
208 bd_srv_t *srv;
209
210 srv = calloc(1, sizeof(bd_srv_t));
211 if (srv == NULL)
212 return NULL;
213
214 srv->srvs = srvs;
215 return srv;
216}
217
218void bd_srvs_init(bd_srvs_t *srvs)
219{
220 srvs->ops = NULL;
221 srvs->sarg = NULL;
222}
223
224errno_t bd_conn(ipc_call_t *icall, bd_srvs_t *srvs)
225{
226 bd_srv_t *srv;
227 errno_t rc;
228
229 /* Accept the connection */
230 async_answer_0(icall, EOK);
231
232 srv = bd_srv_create(srvs);
233 if (srv == NULL)
234 return ENOMEM;
235
236 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
237 if (sess == NULL)
238 return ENOMEM;
239
240 srv->client_sess = sess;
241
242 rc = srvs->ops->open(srvs, srv);
243 if (rc != EOK)
244 return rc;
245
246 while (true) {
247 ipc_call_t call;
248 async_get_call(&call);
249 sysarg_t method = IPC_GET_IMETHOD(call);
250
251 if (!method) {
252 /* The other side has hung up */
253 async_answer_0(&call, EOK);
254 break;
255 }
256
257 switch (method) {
258 case BD_READ_BLOCKS:
259 bd_read_blocks_srv(srv, &call);
260 break;
261 case BD_READ_TOC:
262 bd_read_toc_srv(srv, &call);
263 break;
264 case BD_SYNC_CACHE:
265 bd_sync_cache_srv(srv, &call);
266 break;
267 case BD_WRITE_BLOCKS:
268 bd_write_blocks_srv(srv, &call);
269 break;
270 case BD_GET_BLOCK_SIZE:
271 bd_get_block_size_srv(srv, &call);
272 break;
273 case BD_GET_NUM_BLOCKS:
274 bd_get_num_blocks_srv(srv, &call);
275 break;
276 default:
277 async_answer_0(&call, EINVAL);
278 }
279 }
280
281 rc = srvs->ops->close(srv);
282 free(srv);
283
284 return rc;
285}
286
287/** @}
288 */
Note: See TracBrowser for help on using the repository browser.