source: mainline/uspace/lib/c/generic/bd_srv.c@ 1be7bee

Last change on this file since 1be7bee was fafb8e5, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 6 years ago

Mechanically lowercase IPC_SET_*/IPC_GET_*

  • 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_accept_0(icall);
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.