source: mainline/uspace/lib/usbvirt/src/ipc_hc.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * Copyright (c) 2011 Vojtech Horky
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 libusbvirt
30 * @{
31 */
32/** @file
33 * IPC wrappers, host controller side.
34 */
35#include <errno.h>
36#include <str.h>
37#include <stdio.h>
38#include <assert.h>
39#include <async.h>
40#include <usbvirt/device.h>
41#include <usbvirt/ipc.h>
42#include <usb/debug.h>
43
44/** Send control read transfer to virtual USB device.
45 *
46 * @param sess Session to the virtual device.
47 * @param ep Target endpoint number.
48 * @param setup_buffer Setup buffer.
49 * @param setup_buffer_size Setup buffer size in bytes.
50 * @param data_buffer Data buffer (DATA stage of control transfer).
51 * @param data_buffer_size Size of data buffer in bytes.
52 * @param data_transferred_size Number of actually transferred bytes.
53 *
54 * @return Error code.
55 *
56 */
57errno_t usbvirt_ipc_send_control_read(async_sess_t *sess, void *setup_buffer,
58 size_t setup_buffer_size, void *data_buffer, size_t data_buffer_size,
59 size_t *data_transferred_size)
60{
61 if (!sess)
62 return EINVAL;
63
64 if ((setup_buffer == NULL) || (setup_buffer_size == 0))
65 return EINVAL;
66
67 if ((data_buffer == NULL) || (data_buffer_size == 0))
68 return EINVAL;
69
70 async_exch_t *exch = async_exchange_begin(sess);
71
72 aid_t opening_request = async_send_0(exch, IPC_M_USBVIRT_CONTROL_READ,
73 NULL);
74 if (opening_request == 0) {
75 async_exchange_end(exch);
76 return ENOMEM;
77 }
78
79 errno_t rc = async_data_write_start(exch, setup_buffer,
80 setup_buffer_size);
81 if (rc != EOK) {
82 async_exchange_end(exch);
83 async_forget(opening_request);
84 return rc;
85 }
86
87 ipc_call_t data_request_call;
88 aid_t data_request = async_data_read(exch, data_buffer,
89 data_buffer_size, &data_request_call);
90
91 async_exchange_end(exch);
92
93 if (data_request == 0) {
94 async_forget(opening_request);
95 return ENOMEM;
96 }
97
98 errno_t data_request_rc;
99 errno_t opening_request_rc;
100 async_wait_for(data_request, &data_request_rc);
101 async_wait_for(opening_request, &opening_request_rc);
102
103 if (data_request_rc != EOK) {
104 /* Prefer the return code of the opening request. */
105 if (opening_request_rc != EOK)
106 return (errno_t) opening_request_rc;
107 else
108 return (errno_t) data_request_rc;
109 }
110
111 if (opening_request_rc != EOK)
112 return (errno_t) opening_request_rc;
113
114 if (data_transferred_size != NULL)
115 *data_transferred_size = IPC_GET_ARG2(data_request_call);
116
117 return EOK;
118}
119
120/** Send control write transfer to virtual USB device.
121 *
122 * @param sess Session to the virtual device.
123 * @param ep Target endpoint number.
124 * @param setup_buffer Setup buffer.
125 * @param setup_buffer_size Setup buffer size in bytes.
126 * @param data_buffer Data buffer (DATA stage of control transfer).
127 * @param data_buffer_size Size of data buffer in bytes.
128 *
129 * @return Error code.
130 *
131 */
132errno_t usbvirt_ipc_send_control_write(async_sess_t *sess, void *setup_buffer,
133 size_t setup_buffer_size, void *data_buffer, size_t data_buffer_size)
134{
135 if (!sess)
136 return EINVAL;
137
138 if ((setup_buffer == NULL) || (setup_buffer_size == 0))
139 return EINVAL;
140
141 if ((data_buffer_size > 0) && (data_buffer == NULL))
142 return EINVAL;
143
144 async_exch_t *exch = async_exchange_begin(sess);
145
146 aid_t opening_request = async_send_1(exch, IPC_M_USBVIRT_CONTROL_WRITE,
147 data_buffer_size, NULL);
148 if (opening_request == 0) {
149 async_exchange_end(exch);
150 return ENOMEM;
151 }
152
153 errno_t rc = async_data_write_start(exch, setup_buffer,
154 setup_buffer_size);
155 if (rc != EOK) {
156 async_exchange_end(exch);
157 async_forget(opening_request);
158 return rc;
159 }
160
161 if (data_buffer_size > 0) {
162 rc = async_data_write_start(exch, data_buffer,
163 data_buffer_size);
164 if (rc != EOK) {
165 async_exchange_end(exch);
166 async_forget(opening_request);
167 return rc;
168 }
169 }
170
171 async_exchange_end(exch);
172
173 errno_t opening_request_rc;
174 async_wait_for(opening_request, &opening_request_rc);
175
176 return (errno_t) opening_request_rc;
177}
178
179/** Request data transfer from virtual USB device.
180 *
181 * @param sess Session to the virtual device.
182 * @param ep Target endpoint number.
183 * @param tr_type Transfer type (interrupt or bulk).
184 * @param data Data buffer.
185 * @param data_size Size of the data buffer in bytes.
186 * @param act_size Number of actually returned bytes.
187 *
188 * @return Error code.
189 *
190 */
191errno_t usbvirt_ipc_send_data_in(async_sess_t *sess, usb_endpoint_t ep,
192 usb_transfer_type_t tr_type, void *data, size_t data_size, size_t *act_size)
193{
194 if (!sess)
195 return EINVAL;
196
197 usbvirt_hc_to_device_method_t method;
198
199 switch (tr_type) {
200 case USB_TRANSFER_INTERRUPT:
201 method = IPC_M_USBVIRT_INTERRUPT_IN;
202 break;
203 case USB_TRANSFER_BULK:
204 method = IPC_M_USBVIRT_BULK_IN;
205 break;
206 default:
207 return EINVAL;
208 }
209
210 if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX))
211 return EINVAL;
212
213 if ((data == NULL) || (data_size == 0))
214 return EINVAL;
215
216 async_exch_t *exch = async_exchange_begin(sess);
217
218 aid_t opening_request = async_send_2(exch, method, ep, tr_type, NULL);
219 if (opening_request == 0) {
220 async_exchange_end(exch);
221 return ENOMEM;
222 }
223
224 ipc_call_t data_request_call;
225 aid_t data_request = async_data_read(exch, data, data_size,
226 &data_request_call);
227
228 async_exchange_end(exch);
229
230 if (data_request == 0) {
231 async_forget(opening_request);
232 return ENOMEM;
233 }
234
235 errno_t data_request_rc;
236 errno_t opening_request_rc;
237 async_wait_for(data_request, &data_request_rc);
238 async_wait_for(opening_request, &opening_request_rc);
239
240 if (data_request_rc != EOK) {
241 /* Prefer the return code of the opening request. */
242 if (opening_request_rc != EOK)
243 return (errno_t) opening_request_rc;
244 else
245 return (errno_t) data_request_rc;
246 }
247
248 if (opening_request_rc != EOK)
249 return (errno_t) opening_request_rc;
250
251 if (act_size != NULL)
252 *act_size = IPC_GET_ARG2(data_request_call);
253
254 return EOK;
255}
256
257/** Send data to virtual USB device.
258 *
259 * @param sess Session to the virtual device.
260 * @param ep Target endpoint number.
261 * @param tr_type Transfer type (interrupt or bulk).
262 * @param data Data buffer.
263 * @param data_size Size of the data buffer in bytes.
264 *
265 * @return Error code.
266 *
267 */
268errno_t usbvirt_ipc_send_data_out(async_sess_t *sess, usb_endpoint_t ep,
269 usb_transfer_type_t tr_type, void *data, size_t data_size)
270{
271 if (!sess)
272 return EINVAL;
273
274 usbvirt_hc_to_device_method_t method;
275
276 switch (tr_type) {
277 case USB_TRANSFER_INTERRUPT:
278 method = IPC_M_USBVIRT_INTERRUPT_OUT;
279 break;
280 case USB_TRANSFER_BULK:
281 method = IPC_M_USBVIRT_BULK_OUT;
282 break;
283 default:
284 return EINVAL;
285 }
286
287 if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX))
288 return EINVAL;
289
290 if ((data == NULL) || (data_size == 0))
291 return EINVAL;
292
293 async_exch_t *exch = async_exchange_begin(sess);
294
295 aid_t opening_request = async_send_1(exch, method, ep, NULL);
296 if (opening_request == 0) {
297 async_exchange_end(exch);
298 return ENOMEM;
299 }
300
301 errno_t rc = async_data_write_start(exch, data, data_size);
302
303 async_exchange_end(exch);
304
305 if (rc != EOK) {
306 async_forget(opening_request);
307 return rc;
308 }
309
310 errno_t opening_request_rc;
311 async_wait_for(opening_request, &opening_request_rc);
312
313 return (errno_t) opening_request_rc;
314}
315
316/**
317 * @}
318 */
Note: See TracBrowser for help on using the repository browser.