source: mainline/uspace/lib/drv/generic/remote_usbdiag.c

Last change on this file 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.2 KB
Line 
1/*
2 * Copyright (c) 2017 Petr Manek
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 libdrv
30 * @{
31 */
32/** @file
33 * USB diagnostic device remote interface.
34 */
35
36#include <async.h>
37#include <assert.h>
38#include <macros.h>
39#include <errno.h>
40#include <devman.h>
41
42#include "usbdiag_iface.h"
43
44typedef enum {
45 IPC_M_USBDIAG_TEST_IN,
46 IPC_M_USBDIAG_TEST_OUT,
47} usb_iface_funcs_t;
48
49async_sess_t *usbdiag_connect(devman_handle_t handle)
50{
51 return devman_device_connect(handle, IPC_FLAG_BLOCKING);
52}
53
54void usbdiag_disconnect(async_sess_t *sess)
55{
56 if (sess)
57 async_hangup(sess);
58}
59
60errno_t usbdiag_test_in(async_exch_t *exch,
61 const usbdiag_test_params_t *params, usbdiag_test_results_t *results)
62{
63 if (!exch)
64 return EBADMEM;
65
66 ipc_call_t answer;
67 aid_t req = async_send_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE),
68 IPC_M_USBDIAG_TEST_IN, &answer);
69
70 errno_t rc = async_data_write_start(exch, params,
71 sizeof(usbdiag_test_params_t));
72 if (rc != EOK) {
73 async_exchange_end(exch);
74 async_forget(req);
75 return rc;
76 }
77
78 rc = async_data_read_start(exch, results,
79 sizeof(usbdiag_test_results_t));
80 if (rc != EOK) {
81 async_exchange_end(exch);
82 async_forget(req);
83 return rc;
84 }
85
86 async_exchange_end(exch);
87
88 errno_t retval;
89 async_wait_for(req, &retval);
90
91 return (errno_t) retval;
92}
93
94errno_t usbdiag_test_out(async_exch_t *exch,
95 const usbdiag_test_params_t *params, usbdiag_test_results_t *results)
96{
97 if (!exch)
98 return EBADMEM;
99
100 ipc_call_t answer;
101 aid_t req = async_send_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE),
102 IPC_M_USBDIAG_TEST_OUT, &answer);
103
104 errno_t rc = async_data_write_start(exch, params,
105 sizeof(usbdiag_test_params_t));
106 if (rc != EOK) {
107 async_exchange_end(exch);
108 async_forget(req);
109 return rc;
110 }
111
112 rc = async_data_read_start(exch, results,
113 sizeof(usbdiag_test_results_t));
114 if (rc != EOK) {
115 async_exchange_end(exch);
116 async_forget(req);
117 return rc;
118 }
119
120 async_exchange_end(exch);
121
122 errno_t retval;
123 async_wait_for(req, &retval);
124
125 return (errno_t) retval;
126}
127
128static void remote_usbdiag_test_in(ddf_fun_t *, void *, ipc_call_t *);
129static void remote_usbdiag_test_out(ddf_fun_t *, void *, ipc_call_t *);
130
131/** Remote USB diagnostic interface operations. */
132static const remote_iface_func_ptr_t remote_usbdiag_iface_ops [] = {
133 [IPC_M_USBDIAG_TEST_IN] = remote_usbdiag_test_in,
134 [IPC_M_USBDIAG_TEST_OUT] = remote_usbdiag_test_out
135};
136
137/** Remote USB diagnostic interface structure. */
138const remote_iface_t remote_usbdiag_iface = {
139 .method_count = ARRAY_SIZE(remote_usbdiag_iface_ops),
140 .methods = remote_usbdiag_iface_ops,
141};
142
143void remote_usbdiag_test_in(ddf_fun_t *fun, void *iface, ipc_call_t *call)
144{
145 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface;
146
147 ipc_call_t data;
148 size_t size;
149 if (!async_data_write_receive(&data, &size)) {
150 async_answer_0(&data, EINVAL);
151 async_answer_0(call, EINVAL);
152 return;
153 }
154
155 if (size != sizeof(usbdiag_test_params_t)) {
156 async_answer_0(&data, EINVAL);
157 async_answer_0(call, EINVAL);
158 return;
159 }
160
161 usbdiag_test_params_t params;
162 if (async_data_write_finalize(&data, &params, size) != EOK) {
163 async_answer_0(call, EINVAL);
164 return;
165 }
166
167 usbdiag_test_results_t results;
168 const errno_t ret = !diag_iface->test_in ? ENOTSUP :
169 diag_iface->test_in(fun, &params, &results);
170
171 if (ret != EOK) {
172 async_answer_0(call, ret);
173 return;
174 }
175
176 if (!async_data_read_receive(&data, &size)) {
177 async_answer_0(&data, EINVAL);
178 async_answer_0(call, EINVAL);
179 return;
180 }
181
182 if (size != sizeof(usbdiag_test_results_t)) {
183 async_answer_0(&data, EINVAL);
184 async_answer_0(call, EINVAL);
185 return;
186 }
187
188 if (async_data_read_finalize(&data, &results, size) != EOK) {
189 async_answer_0(call, EINVAL);
190 return;
191 }
192
193 async_answer_0(call, ret);
194}
195
196void remote_usbdiag_test_out(ddf_fun_t *fun, void *iface, ipc_call_t *call)
197{
198 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface;
199
200 ipc_call_t data;
201 size_t size;
202 if (!async_data_write_receive(&data, &size)) {
203 async_answer_0(&data, EINVAL);
204 async_answer_0(call, EINVAL);
205 return;
206 }
207
208 if (size != sizeof(usbdiag_test_params_t)) {
209 async_answer_0(&data, EINVAL);
210 async_answer_0(call, EINVAL);
211 return;
212 }
213
214 usbdiag_test_params_t params;
215 if (async_data_write_finalize(&data, &params, size) != EOK) {
216 async_answer_0(call, EINVAL);
217 return;
218 }
219
220 usbdiag_test_results_t results;
221 const errno_t ret = !diag_iface->test_out ? ENOTSUP :
222 diag_iface->test_out(fun, &params, &results);
223
224 if (ret != EOK) {
225 async_answer_0(call, ret);
226 return;
227 }
228
229 if (!async_data_read_receive(&data, &size)) {
230 async_answer_0(&data, EINVAL);
231 async_answer_0(call, EINVAL);
232 return;
233 }
234
235 if (size != sizeof(usbdiag_test_results_t)) {
236 async_answer_0(&data, EINVAL);
237 async_answer_0(call, EINVAL);
238 return;
239 }
240
241 if (async_data_read_finalize(&data, &results, size) != EOK) {
242 async_answer_0(call, EINVAL);
243 return;
244 }
245
246 async_answer_0(call, ret);
247}
248
249/**
250 * @}
251 */
Note: See TracBrowser for help on using the repository browser.