source: mainline/uspace/lib/drv/generic/remote_usbdiag.c@ 3061bc1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3061bc1 was ae3a941, checked in by Ondřej Hlavatý <aearsis@…>, 7 years ago

usb: cstyle

  • Property mode set to 100644
File size: 6.4 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 *,
129 ipc_callid_t, ipc_call_t *);
130static void remote_usbdiag_test_out(ddf_fun_t *, void *,
131 ipc_callid_t, ipc_call_t *);
132
133/** Remote USB diagnostic interface operations. */
134static const remote_iface_func_ptr_t remote_usbdiag_iface_ops [] = {
135 [IPC_M_USBDIAG_TEST_IN] = remote_usbdiag_test_in,
136 [IPC_M_USBDIAG_TEST_OUT] = remote_usbdiag_test_out
137};
138
139/** Remote USB diagnostic interface structure. */
140const remote_iface_t remote_usbdiag_iface = {
141 .method_count = ARRAY_SIZE(remote_usbdiag_iface_ops),
142 .methods = remote_usbdiag_iface_ops,
143};
144
145void remote_usbdiag_test_in(ddf_fun_t *fun, void *iface,
146 ipc_callid_t callid, ipc_call_t *call)
147{
148 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface;
149
150 size_t size;
151 ipc_callid_t data_callid;
152 if (!async_data_write_receive(&data_callid, &size)) {
153 async_answer_0(data_callid, EINVAL);
154 async_answer_0(callid, EINVAL);
155 return;
156 }
157
158 if (size != sizeof(usbdiag_test_params_t)) {
159 async_answer_0(data_callid, EINVAL);
160 async_answer_0(callid, EINVAL);
161 return;
162 }
163
164 usbdiag_test_params_t params;
165 if (async_data_write_finalize(data_callid, &params, size) != EOK) {
166 async_answer_0(callid, EINVAL);
167 return;
168 }
169
170 usbdiag_test_results_t results;
171 const errno_t ret = !diag_iface->test_in ? ENOTSUP
172 : diag_iface->test_in(fun, &params, &results);
173
174 if (ret != EOK) {
175 async_answer_0(callid, ret);
176 return;
177 }
178
179 if (!async_data_read_receive(&data_callid, &size)) {
180 async_answer_0(data_callid, EINVAL);
181 async_answer_0(callid, EINVAL);
182 return;
183 }
184
185 if (size != sizeof(usbdiag_test_results_t)) {
186 async_answer_0(data_callid, EINVAL);
187 async_answer_0(callid, EINVAL);
188 return;
189 }
190
191 if (async_data_read_finalize(data_callid, &results, size) != EOK) {
192 async_answer_0(callid, EINVAL);
193 return;
194 }
195
196 async_answer_0(callid, ret);
197}
198
199void remote_usbdiag_test_out(ddf_fun_t *fun, void *iface,
200 ipc_callid_t callid, ipc_call_t *call)
201{
202 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface;
203
204 size_t size;
205 ipc_callid_t data_callid;
206 if (!async_data_write_receive(&data_callid, &size)) {
207 async_answer_0(data_callid, EINVAL);
208 async_answer_0(callid, EINVAL);
209 return;
210 }
211
212 if (size != sizeof(usbdiag_test_params_t)) {
213 async_answer_0(data_callid, EINVAL);
214 async_answer_0(callid, EINVAL);
215 return;
216 }
217
218 usbdiag_test_params_t params;
219 if (async_data_write_finalize(data_callid, &params, size) != EOK) {
220 async_answer_0(callid, EINVAL);
221 return;
222 }
223
224 usbdiag_test_results_t results;
225 const errno_t ret = !diag_iface->test_out ? ENOTSUP
226 : diag_iface->test_out(fun, &params, &results);
227
228 if (ret != EOK) {
229 async_answer_0(callid, ret);
230 return;
231 }
232
233 if (!async_data_read_receive(&data_callid, &size)) {
234 async_answer_0(data_callid, EINVAL);
235 async_answer_0(callid, EINVAL);
236 return;
237 }
238
239 if (size != sizeof(usbdiag_test_results_t)) {
240 async_answer_0(data_callid, EINVAL);
241 async_answer_0(callid, EINVAL);
242 return;
243 }
244
245 if (async_data_read_finalize(data_callid, &results, size) != EOK) {
246 async_answer_0(callid, EINVAL);
247 return;
248 }
249
250 async_answer_0(callid, ret);
251}
252
253/**
254 * @}
255 */
Note: See TracBrowser for help on using the repository browser.