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

Last change on this file since 7fa8589 was 7fa8589, checked in by Matthieu Riolo <matthieu.riolo@…>, 5 years ago

Removing unneeded casts from errno_t to errno_t

  • Property mode set to 100644
File size: 8.1 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 opening_request_rc;
107 else
108 return data_request_rc;
109 }
110
111 if (opening_request_rc != EOK)
112 return 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 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 opening_request_rc;
244 else
245 return data_request_rc;
246 }
247
248 if (opening_request_rc != EOK)
249 return 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 opening_request_rc;
314}
315
316/**
317 * @}
318 */
Note: See TracBrowser for help on using the repository browser.