Add missing calls to refcount_init()
[helenos.git] / uspace / lib / drv / generic / remote_usbdiag.c
blob633f52e56ef015b81c2bbfe14a5e0dc68433f9e4
1 /*
2 * Copyright (c) 2017 Petr Manek
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
30 * @{
32 /** @file
33 * USB diagnostic device remote interface.
36 #include <async.h>
37 #include <assert.h>
38 #include <macros.h>
39 #include <errno.h>
40 #include <devman.h>
42 #include "usbdiag_iface.h"
44 typedef enum {
45 IPC_M_USBDIAG_TEST_IN,
46 IPC_M_USBDIAG_TEST_OUT,
47 } usb_iface_funcs_t;
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)
56 if (sess)
57 async_hangup(sess);
60 errno_t usbdiag_test_in(async_exch_t *exch,
61 const usbdiag_test_params_t *params, usbdiag_test_results_t *results)
63 if (!exch)
64 return EBADMEM;
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);
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;
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;
86 async_exchange_end(exch);
88 errno_t retval;
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)
97 if (!exch)
98 return EBADMEM;
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);
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;
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;
120 async_exchange_end(exch);
122 errno_t retval;
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;
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;
155 if (size != sizeof(usbdiag_test_params_t)) {
156 async_answer_0(&data, EINVAL);
157 async_answer_0(call, EINVAL);
158 return;
161 usbdiag_test_params_t params;
162 if (async_data_write_finalize(&data, &params, size) != EOK) {
163 async_answer_0(call, EINVAL);
164 return;
167 usbdiag_test_results_t results;
168 const errno_t ret = !diag_iface->test_in ? ENOTSUP :
169 diag_iface->test_in(fun, &params, &results);
171 if (ret != EOK) {
172 async_answer_0(call, ret);
173 return;
176 if (!async_data_read_receive(&data, &size)) {
177 async_answer_0(&data, EINVAL);
178 async_answer_0(call, EINVAL);
179 return;
182 if (size != sizeof(usbdiag_test_results_t)) {
183 async_answer_0(&data, EINVAL);
184 async_answer_0(call, EINVAL);
185 return;
188 if (async_data_read_finalize(&data, &results, size) != EOK) {
189 async_answer_0(call, EINVAL);
190 return;
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;
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;
208 if (size != sizeof(usbdiag_test_params_t)) {
209 async_answer_0(&data, EINVAL);
210 async_answer_0(call, EINVAL);
211 return;
214 usbdiag_test_params_t params;
215 if (async_data_write_finalize(&data, &params, size) != EOK) {
216 async_answer_0(call, EINVAL);
217 return;
220 usbdiag_test_results_t results;
221 const errno_t ret = !diag_iface->test_out ? ENOTSUP :
222 diag_iface->test_out(fun, &params, &results);
224 if (ret != EOK) {
225 async_answer_0(call, ret);
226 return;
229 if (!async_data_read_receive(&data, &size)) {
230 async_answer_0(&data, EINVAL);
231 async_answer_0(call, EINVAL);
232 return;
235 if (size != sizeof(usbdiag_test_results_t)) {
236 async_answer_0(&data, EINVAL);
237 async_answer_0(call, EINVAL);
238 return;
241 if (async_data_read_finalize(&data, &results, size) != EOK) {
242 async_answer_0(call, EINVAL);
243 return;
246 async_answer_0(call, ret);
250 * @}