2 * Copyright (c) 2017 Petr Manek
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 /** @addtogroup libdrv
33 * USB diagnostic device remote interface.
42 #include "usbdiag_iface.h"
45 IPC_M_USBDIAG_TEST_IN
,
46 IPC_M_USBDIAG_TEST_OUT
,
49 async_sess_t
*usbdiag_connect(devman_handle_t handle
)
51 return devman_device_connect(handle
, IPC_FLAG_BLOCKING
);
54 void usbdiag_disconnect(async_sess_t
*sess
)
60 errno_t
usbdiag_test_in(async_exch_t
*exch
,
61 const usbdiag_test_params_t
*params
, usbdiag_test_results_t
*results
)
67 aid_t req
= async_send_1(exch
, DEV_IFACE_ID(USBDIAG_DEV_IFACE
),
68 IPC_M_USBDIAG_TEST_IN
, &answer
);
70 errno_t rc
= async_data_write_start(exch
, params
,
71 sizeof(usbdiag_test_params_t
));
73 async_exchange_end(exch
);
78 rc
= async_data_read_start(exch
, results
,
79 sizeof(usbdiag_test_results_t
));
81 async_exchange_end(exch
);
86 async_exchange_end(exch
);
89 async_wait_for(req
, &retval
);
91 return (errno_t
) retval
;
94 errno_t
usbdiag_test_out(async_exch_t
*exch
,
95 const usbdiag_test_params_t
*params
, usbdiag_test_results_t
*results
)
101 aid_t req
= async_send_1(exch
, DEV_IFACE_ID(USBDIAG_DEV_IFACE
),
102 IPC_M_USBDIAG_TEST_OUT
, &answer
);
104 errno_t rc
= async_data_write_start(exch
, params
,
105 sizeof(usbdiag_test_params_t
));
107 async_exchange_end(exch
);
112 rc
= async_data_read_start(exch
, results
,
113 sizeof(usbdiag_test_results_t
));
115 async_exchange_end(exch
);
120 async_exchange_end(exch
);
123 async_wait_for(req
, &retval
);
125 return (errno_t
) retval
;
128 static void remote_usbdiag_test_in(ddf_fun_t
*, void *, ipc_call_t
*);
129 static void remote_usbdiag_test_out(ddf_fun_t
*, void *, ipc_call_t
*);
131 /** Remote USB diagnostic interface operations. */
132 static 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
137 /** Remote USB diagnostic interface structure. */
138 const remote_iface_t remote_usbdiag_iface
= {
139 .method_count
= ARRAY_SIZE(remote_usbdiag_iface_ops
),
140 .methods
= remote_usbdiag_iface_ops
,
143 void remote_usbdiag_test_in(ddf_fun_t
*fun
, void *iface
, ipc_call_t
*call
)
145 const usbdiag_iface_t
*diag_iface
= (usbdiag_iface_t
*) iface
;
149 if (!async_data_write_receive(&data
, &size
)) {
150 async_answer_0(&data
, EINVAL
);
151 async_answer_0(call
, EINVAL
);
155 if (size
!= sizeof(usbdiag_test_params_t
)) {
156 async_answer_0(&data
, EINVAL
);
157 async_answer_0(call
, EINVAL
);
161 usbdiag_test_params_t params
;
162 if (async_data_write_finalize(&data
, ¶ms
, size
) != EOK
) {
163 async_answer_0(call
, EINVAL
);
167 usbdiag_test_results_t results
;
168 const errno_t ret
= !diag_iface
->test_in
? ENOTSUP
:
169 diag_iface
->test_in(fun
, ¶ms
, &results
);
172 async_answer_0(call
, ret
);
176 if (!async_data_read_receive(&data
, &size
)) {
177 async_answer_0(&data
, EINVAL
);
178 async_answer_0(call
, EINVAL
);
182 if (size
!= sizeof(usbdiag_test_results_t
)) {
183 async_answer_0(&data
, EINVAL
);
184 async_answer_0(call
, EINVAL
);
188 if (async_data_read_finalize(&data
, &results
, size
) != EOK
) {
189 async_answer_0(call
, EINVAL
);
193 async_answer_0(call
, ret
);
196 void remote_usbdiag_test_out(ddf_fun_t
*fun
, void *iface
, ipc_call_t
*call
)
198 const usbdiag_iface_t
*diag_iface
= (usbdiag_iface_t
*) iface
;
202 if (!async_data_write_receive(&data
, &size
)) {
203 async_answer_0(&data
, EINVAL
);
204 async_answer_0(call
, EINVAL
);
208 if (size
!= sizeof(usbdiag_test_params_t
)) {
209 async_answer_0(&data
, EINVAL
);
210 async_answer_0(call
, EINVAL
);
214 usbdiag_test_params_t params
;
215 if (async_data_write_finalize(&data
, ¶ms
, size
) != EOK
) {
216 async_answer_0(call
, EINVAL
);
220 usbdiag_test_results_t results
;
221 const errno_t ret
= !diag_iface
->test_out
? ENOTSUP
:
222 diag_iface
->test_out(fun
, ¶ms
, &results
);
225 async_answer_0(call
, ret
);
229 if (!async_data_read_receive(&data
, &size
)) {
230 async_answer_0(&data
, EINVAL
);
231 async_answer_0(call
, EINVAL
);
235 if (size
!= sizeof(usbdiag_test_results_t
)) {
236 async_answer_0(&data
, EINVAL
);
237 async_answer_0(call
, EINVAL
);
241 if (async_data_read_finalize(&data
, &results
, size
) != EOK
) {
242 async_answer_0(call
, EINVAL
);
246 async_answer_0(call
, ret
);