source: mainline/uspace/lib/c/generic/bd_srv.c@ 76f566d

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

Prefer handle over ID in naming handle variables

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[4802dd7]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>
[8d2dd7f2]40#include <stddef.h>
41#include <stdint.h>
[4802dd7]42
43#include <bd_srv.h>
44
[a46e56b]45static void bd_read_blocks_srv(bd_srv_t *srv, cap_call_handle_t chandle,
[4802dd7]46 ipc_call_t *call)
47{
48 aoff64_t ba;
49 size_t cnt;
50 void *buf;
51 size_t size;
[b7fd2a0]52 errno_t rc;
[a46e56b]53 cap_call_handle_t rcall_handle;
[4802dd7]54
55 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
56 cnt = IPC_GET_ARG3(*call);
57
[a46e56b]58 if (!async_data_read_receive(&rcall_handle, &size)) {
59 async_answer_0(chandle, EINVAL);
[4802dd7]60 return;
61 }
62
63 buf = malloc(size);
64 if (buf == NULL) {
[a46e56b]65 async_answer_0(rcall_handle, ENOMEM);
66 async_answer_0(chandle, ENOMEM);
[4802dd7]67 return;
68 }
69
[135486d]70 if (srv->srvs->ops->read_blocks == NULL) {
[a46e56b]71 async_answer_0(rcall_handle, ENOTSUP);
72 async_answer_0(chandle, ENOTSUP);
[ccfe9c3]73 free(buf);
[4802dd7]74 return;
75 }
76
[135486d]77 rc = srv->srvs->ops->read_blocks(srv, ba, cnt, buf, size);
[4802dd7]78 if (rc != EOK) {
[a46e56b]79 async_answer_0(rcall_handle, ENOMEM);
80 async_answer_0(chandle, ENOMEM);
[ccfe9c3]81 free(buf);
[4802dd7]82 return;
83 }
84
[a46e56b]85 async_data_read_finalize(rcall_handle, buf, size);
[4802dd7]86
87 free(buf);
[a46e56b]88 async_answer_0(chandle, EOK);
[4802dd7]89}
90
[a46e56b]91static void bd_read_toc_srv(bd_srv_t *srv, cap_call_handle_t chandle,
[4802dd7]92 ipc_call_t *call)
93{
94 uint8_t session;
95 void *buf;
96 size_t size;
[b7fd2a0]97 errno_t rc;
[a46e56b]98 cap_call_handle_t rcall_handle;
[4802dd7]99
100 session = IPC_GET_ARG1(*call);
101
[a46e56b]102 if (!async_data_read_receive(&rcall_handle, &size)) {
103 async_answer_0(chandle, EINVAL);
[4802dd7]104 return;
105 }
106
107 buf = malloc(size);
108 if (buf == NULL) {
[a46e56b]109 async_answer_0(rcall_handle, ENOMEM);
110 async_answer_0(chandle, ENOMEM);
[4802dd7]111 return;
112 }
113
[135486d]114 if (srv->srvs->ops->read_toc == NULL) {
[a46e56b]115 async_answer_0(rcall_handle, ENOTSUP);
116 async_answer_0(chandle, ENOTSUP);
[ccfe9c3]117 free(buf);
[4802dd7]118 return;
119 }
120
[135486d]121 rc = srv->srvs->ops->read_toc(srv, session, buf, size);
[4802dd7]122 if (rc != EOK) {
[a46e56b]123 async_answer_0(rcall_handle, ENOMEM);
124 async_answer_0(chandle, ENOMEM);
[ccfe9c3]125 free(buf);
[4802dd7]126 return;
127 }
128
[a46e56b]129 async_data_read_finalize(rcall_handle, buf, size);
[4802dd7]130
131 free(buf);
[a46e56b]132 async_answer_0(chandle, EOK);
[4802dd7]133}
134
[a46e56b]135static void bd_sync_cache_srv(bd_srv_t *srv, cap_call_handle_t chandle,
[dd8b6a8]136 ipc_call_t *call)
137{
138 aoff64_t ba;
139 size_t cnt;
[b7fd2a0]140 errno_t rc;
[dd8b6a8]141
142 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
143 cnt = IPC_GET_ARG3(*call);
144
145 if (srv->srvs->ops->sync_cache == NULL) {
[a46e56b]146 async_answer_0(chandle, ENOTSUP);
[dd8b6a8]147 return;
148 }
149
150 rc = srv->srvs->ops->sync_cache(srv, ba, cnt);
[a46e56b]151 async_answer_0(chandle, rc);
[dd8b6a8]152}
153
[a46e56b]154static void bd_write_blocks_srv(bd_srv_t *srv, cap_call_handle_t chandle,
[4802dd7]155 ipc_call_t *call)
156{
157 aoff64_t ba;
158 size_t cnt;
159 void *data;
160 size_t size;
[b7fd2a0]161 errno_t rc;
[4802dd7]162
163 ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
164 cnt = IPC_GET_ARG3(*call);
165
166 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
167 if (rc != EOK) {
[a46e56b]168 async_answer_0(chandle, rc);
[4802dd7]169 return;
170 }
171
[135486d]172 if (srv->srvs->ops->write_blocks == NULL) {
[a46e56b]173 async_answer_0(chandle, ENOTSUP);
[4802dd7]174 return;
175 }
176
[135486d]177 rc = srv->srvs->ops->write_blocks(srv, ba, cnt, data, size);
[4802dd7]178 free(data);
[a46e56b]179 async_answer_0(chandle, rc);
[4802dd7]180}
181
[a46e56b]182static void bd_get_block_size_srv(bd_srv_t *srv, cap_call_handle_t chandle,
[4802dd7]183 ipc_call_t *call)
184{
[b7fd2a0]185 errno_t rc;
[4802dd7]186 size_t block_size;
187
[135486d]188 if (srv->srvs->ops->get_block_size == NULL) {
[a46e56b]189 async_answer_0(chandle, ENOTSUP);
[4802dd7]190 return;
191 }
192
[135486d]193 rc = srv->srvs->ops->get_block_size(srv, &block_size);
[a46e56b]194 async_answer_1(chandle, rc, block_size);
[4802dd7]195}
196
[a46e56b]197static void bd_get_num_blocks_srv(bd_srv_t *srv, cap_call_handle_t chandle,
[4802dd7]198 ipc_call_t *call)
199{
[b7fd2a0]200 errno_t rc;
[4802dd7]201 aoff64_t num_blocks;
202
[135486d]203 if (srv->srvs->ops->get_num_blocks == NULL) {
[a46e56b]204 async_answer_0(chandle, ENOTSUP);
[4802dd7]205 return;
206 }
207
[135486d]208 rc = srv->srvs->ops->get_num_blocks(srv, &num_blocks);
[a46e56b]209 async_answer_2(chandle, rc, LOWER32(num_blocks), UPPER32(num_blocks));
[4802dd7]210}
211
[135486d]212static bd_srv_t *bd_srv_create(bd_srvs_t *srvs)
[4802dd7]213{
[135486d]214 bd_srv_t *srv;
215
[75751db6]216 srv = calloc(1, sizeof(bd_srv_t));
[135486d]217 if (srv == NULL)
218 return NULL;
219
220 srv->srvs = srvs;
221 return srv;
[4802dd7]222}
223
[135486d]224void bd_srvs_init(bd_srvs_t *srvs)
[4802dd7]225{
[135486d]226 srvs->ops = NULL;
227 srvs->sarg = NULL;
228}
[4802dd7]229
[a46e56b]230errno_t bd_conn(cap_call_handle_t icall_handle, ipc_call_t *icall, bd_srvs_t *srvs)
[135486d]231{
232 bd_srv_t *srv;
[b7fd2a0]233 errno_t rc;
[4802dd7]234
235 /* Accept the connection */
[a46e56b]236 async_answer_0(icall_handle, EOK);
[4802dd7]237
[135486d]238 srv = bd_srv_create(srvs);
239 if (srv == NULL)
240 return ENOMEM;
241
[4802dd7]242 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
243 if (sess == NULL)
244 return ENOMEM;
245
246 srv->client_sess = sess;
247
[135486d]248 rc = srvs->ops->open(srvs, srv);
[4802dd7]249 if (rc != EOK)
250 return rc;
251
252 while (true) {
253 ipc_call_t call;
[a46e56b]254 cap_call_handle_t chandle = async_get_call(&call);
[4802dd7]255 sysarg_t method = IPC_GET_IMETHOD(call);
256
257 if (!method) {
258 /* The other side has hung up */
[a46e56b]259 async_answer_0(chandle, EOK);
[4802dd7]260 break;
261 }
262
263 switch (method) {
264 case BD_READ_BLOCKS:
[a46e56b]265 bd_read_blocks_srv(srv, chandle, &call);
[4802dd7]266 break;
267 case BD_READ_TOC:
[a46e56b]268 bd_read_toc_srv(srv, chandle, &call);
[4802dd7]269 break;
[dd8b6a8]270 case BD_SYNC_CACHE:
[a46e56b]271 bd_sync_cache_srv(srv, chandle, &call);
[dd8b6a8]272 break;
[4802dd7]273 case BD_WRITE_BLOCKS:
[a46e56b]274 bd_write_blocks_srv(srv, chandle, &call);
[4802dd7]275 break;
276 case BD_GET_BLOCK_SIZE:
[a46e56b]277 bd_get_block_size_srv(srv, chandle, &call);
[4802dd7]278 break;
279 case BD_GET_NUM_BLOCKS:
[a46e56b]280 bd_get_num_blocks_srv(srv, chandle, &call);
[4802dd7]281 break;
282 default:
[a46e56b]283 async_answer_0(chandle, EINVAL);
[4802dd7]284 }
285 }
286
[135486d]287 rc = srvs->ops->close(srv);
288 free(srv);
289
290 return rc;
[4802dd7]291}
292
293/** @}
294 */
Note: See TracBrowser for help on using the repository browser.