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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 45457265 was 64ce0c1, checked in by Jenda <jenda.jzqk73@…>, 8 years ago

Merge commit '290338bf7224f502808b23e82d98306208962b97' into forwardport

  • Property mode set to 100644
File size: 6.3 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
60int usbdiag_test_in(async_exch_t *exch, const usbdiag_test_params_t *params, usbdiag_test_results_t *results)
61{
62 if (!exch)
63 return EBADMEM;
64
65 ipc_call_t answer;
66 aid_t req = async_send_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_TEST_IN, &answer);
67
68 int rc = async_data_write_start(exch, params, sizeof(usbdiag_test_params_t));
69 if (rc != EOK) {
70 async_exchange_end(exch);
71 async_forget(req);
72 return rc;
73 }
74
75 rc = async_data_read_start(exch, results, sizeof(usbdiag_test_results_t));
76 if (rc != EOK) {
77 async_exchange_end(exch);
78 async_forget(req);
79 return rc;
80 }
81
82 async_exchange_end(exch);
83
84 errno_t retval;
85 async_wait_for(req, &retval);
86
87 return (int) retval;
88}
89
90int usbdiag_test_out(async_exch_t *exch, const usbdiag_test_params_t *params, usbdiag_test_results_t *results)
91{
92 if (!exch)
93 return EBADMEM;
94
95 ipc_call_t answer;
96 aid_t req = async_send_1(exch, DEV_IFACE_ID(USBDIAG_DEV_IFACE), IPC_M_USBDIAG_TEST_OUT, &answer);
97
98 int rc = async_data_write_start(exch, params, sizeof(usbdiag_test_params_t));
99 if (rc != EOK) {
100 async_exchange_end(exch);
101 async_forget(req);
102 return rc;
103 }
104
105 rc = async_data_read_start(exch, results, sizeof(usbdiag_test_results_t));
106 if (rc != EOK) {
107 async_exchange_end(exch);
108 async_forget(req);
109 return rc;
110 }
111
112 async_exchange_end(exch);
113
114 errno_t retval;
115 async_wait_for(req, &retval);
116
117 return (int) retval;
118}
119
120static void remote_usbdiag_test_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
121static void remote_usbdiag_test_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
122
123/** Remote USB diagnostic interface operations. */
124static const remote_iface_func_ptr_t remote_usbdiag_iface_ops [] = {
125 [IPC_M_USBDIAG_TEST_IN] = remote_usbdiag_test_in,
126 [IPC_M_USBDIAG_TEST_OUT] = remote_usbdiag_test_out
127};
128
129/** Remote USB diagnostic interface structure. */
130const remote_iface_t remote_usbdiag_iface = {
131 .method_count = ARRAY_SIZE(remote_usbdiag_iface_ops),
132 .methods = remote_usbdiag_iface_ops,
133};
134
135void remote_usbdiag_test_in(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
136{
137 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface;
138
139 size_t size;
140 ipc_callid_t data_callid;
141 if (!async_data_write_receive(&data_callid, &size)) {
142 async_answer_0(data_callid, EINVAL);
143 async_answer_0(callid, EINVAL);
144 return;
145 }
146
147 if (size != sizeof(usbdiag_test_params_t)) {
148 async_answer_0(data_callid, EINVAL);
149 async_answer_0(callid, EINVAL);
150 return;
151 }
152
153 usbdiag_test_params_t params;
154 if (async_data_write_finalize(data_callid, &params, size) != EOK) {
155 async_answer_0(callid, EINVAL);
156 return;
157 }
158
159 usbdiag_test_results_t results;
160 const int ret = !diag_iface->test_in ? ENOTSUP : diag_iface->test_in(fun, &params, &results);
161
162 if (ret != EOK) {
163 async_answer_0(callid, ret);
164 return;
165 }
166
167 if (!async_data_read_receive(&data_callid, &size)) {
168 async_answer_0(data_callid, EINVAL);
169 async_answer_0(callid, EINVAL);
170 return;
171 }
172
173 if (size != sizeof(usbdiag_test_results_t)) {
174 async_answer_0(data_callid, EINVAL);
175 async_answer_0(callid, EINVAL);
176 return;
177 }
178
179 if (async_data_read_finalize(data_callid, &results, size) != EOK) {
180 async_answer_0(callid, EINVAL);
181 return;
182 }
183
184 async_answer_0(callid, ret);
185}
186
187void remote_usbdiag_test_out(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
188{
189 const usbdiag_iface_t *diag_iface = (usbdiag_iface_t *) iface;
190
191 size_t size;
192 ipc_callid_t data_callid;
193 if (!async_data_write_receive(&data_callid, &size)) {
194 async_answer_0(data_callid, EINVAL);
195 async_answer_0(callid, EINVAL);
196 return;
197 }
198
199 if (size != sizeof(usbdiag_test_params_t)) {
200 async_answer_0(data_callid, EINVAL);
201 async_answer_0(callid, EINVAL);
202 return;
203 }
204
205 usbdiag_test_params_t params;
206 if (async_data_write_finalize(data_callid, &params, size) != EOK) {
207 async_answer_0(callid, EINVAL);
208 return;
209 }
210
211 usbdiag_test_results_t results;
212 const int ret = !diag_iface->test_out ? ENOTSUP : diag_iface->test_out(fun, &params, &results);
213
214 if (ret != EOK) {
215 async_answer_0(callid, ret);
216 return;
217 }
218
219 if (!async_data_read_receive(&data_callid, &size)) {
220 async_answer_0(data_callid, EINVAL);
221 async_answer_0(callid, EINVAL);
222 return;
223 }
224
225 if (size != sizeof(usbdiag_test_results_t)) {
226 async_answer_0(data_callid, EINVAL);
227 async_answer_0(callid, EINVAL);
228 return;
229 }
230
231 if (async_data_read_finalize(data_callid, &results, size) != EOK) {
232 async_answer_0(callid, EINVAL);
233 return;
234 }
235
236 async_answer_0(callid, ret);
237}
238
239/**
240 * @}
241 */
Note: See TracBrowser for help on using the repository browser.