source: mainline/uspace/lib/usbvirt/src/ipc_dev.c@ fafb8e5

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

Mechanically lowercase IPC_SET_*/IPC_GET_*

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[6cb58e6]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
[e25a849]33 * IPC wrappers, device side.
[6cb58e6]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
[beee81a]44/** Handle VHC request for device name.
45 *
[984a9ba]46 * @param dev Target virtual device.
[beee81a]47 * @param icall The call with the request.
[984a9ba]48 *
[beee81a]49 */
[984a9ba]50static void ipc_get_name(usbvirt_device_t *dev, ipc_call_t *icall)
[6cb58e6]51{
52 if (dev->name == NULL) {
[984a9ba]53 async_answer_0(icall, ENOENT);
[6cb58e6]54 }
55
56 size_t size = str_size(dev->name);
57
[984a9ba]58 ipc_call_t call;
[6cb58e6]59 size_t accepted_size;
[984a9ba]60 if (!async_data_read_receive(&call, &accepted_size)) {
61 async_answer_0(icall, EINVAL);
[6cb58e6]62 return;
63 }
64
65 if (accepted_size > size) {
66 accepted_size = size;
67 }
[984a9ba]68 async_data_read_finalize(&call, dev->name, accepted_size);
[6cb58e6]69
[984a9ba]70 async_answer_1(icall, EOK, accepted_size);
[6cb58e6]71}
72
[beee81a]73/** Handle VHC request for control read from the device.
74 *
[984a9ba]75 * @param dev Target virtual device.
[beee81a]76 * @param icall The call with the request.
[984a9ba]77 *
[beee81a]78 */
[984a9ba]79static void ipc_control_read(usbvirt_device_t *dev, ipc_call_t *icall)
[6cb58e6]80{
[b7fd2a0]81 errno_t rc;
[6cb58e6]82
83 void *setup_packet = NULL;
84 size_t setup_packet_len = 0;
85 size_t data_len = 0;
86
87 rc = async_data_write_accept(&setup_packet, false,
88 1, 1024, 0, &setup_packet_len);
89 if (rc != EOK) {
[984a9ba]90 async_answer_0(icall, rc);
[6cb58e6]91 return;
92 }
93
[984a9ba]94 ipc_call_t data;
95 if (!async_data_read_receive(&data, &data_len)) {
96 async_answer_0(icall, EPARTY);
[6cb58e6]97 free(setup_packet);
98 return;
99 }
100
101 void *buffer = malloc(data_len);
102 if (buffer == NULL) {
[984a9ba]103 async_answer_0(icall, ENOMEM);
[6cb58e6]104 free(setup_packet);
105 return;
106 }
107
108 size_t actual_len;
109 rc = usbvirt_control_read(dev, setup_packet, setup_packet_len,
110 buffer, data_len, &actual_len);
111
112 if (rc != EOK) {
[984a9ba]113 async_answer_0(&data, rc);
114 async_answer_0(icall, rc);
[6cb58e6]115 free(setup_packet);
116 free(buffer);
117 return;
118 }
119
[984a9ba]120 async_data_read_finalize(&data, buffer, actual_len);
121 async_answer_0(icall, EOK);
[6cb58e6]122
123 free(setup_packet);
124 free(buffer);
125}
126
[beee81a]127/** Handle VHC request for control write to the device.
128 *
[984a9ba]129 * @param dev Target virtual device.
[beee81a]130 * @param icall The call with the request.
[984a9ba]131 *
[beee81a]132 */
[984a9ba]133static void ipc_control_write(usbvirt_device_t *dev, ipc_call_t *icall)
[6cb58e6]134{
[fafb8e5]135 size_t data_buffer_len = ipc_get_arg1(icall);
[b7fd2a0]136 errno_t rc;
[6cb58e6]137
138 void *setup_packet = NULL;
139 void *data_buffer = NULL;
140 size_t setup_packet_len = 0;
141
142 rc = async_data_write_accept(&setup_packet, false,
[beee81a]143 1, 0, 0, &setup_packet_len);
[6cb58e6]144 if (rc != EOK) {
[984a9ba]145 async_answer_0(icall, rc);
[6cb58e6]146 return;
147 }
148
149 if (data_buffer_len > 0) {
150 rc = async_data_write_accept(&data_buffer, false,
[beee81a]151 1, 0, 0, &data_buffer_len);
[6cb58e6]152 if (rc != EOK) {
[984a9ba]153 async_answer_0(icall, rc);
[6cb58e6]154 free(setup_packet);
155 return;
156 }
157 }
158
159 rc = usbvirt_control_write(dev, setup_packet, setup_packet_len,
160 data_buffer, data_buffer_len);
161
[984a9ba]162 async_answer_0(icall, rc);
[beee81a]163
164 free(setup_packet);
165 if (data_buffer != NULL) {
166 free(data_buffer);
167 }
[6cb58e6]168}
169
[beee81a]170/** Handle VHC request for data read from the device (in transfer).
171 *
[984a9ba]172 * @param dev Target virtual device.
[beee81a]173 * @param icall The call with the request.
[984a9ba]174 *
[beee81a]175 */
176static void ipc_data_in(usbvirt_device_t *dev,
[984a9ba]177 usb_transfer_type_t transfer_type, ipc_call_t *icall)
[6cb58e6]178{
[fafb8e5]179 usb_endpoint_t endpoint = ipc_get_arg1(icall);
[6cb58e6]180
[b7fd2a0]181 errno_t rc;
[6cb58e6]182
183 size_t data_len = 0;
[984a9ba]184 ipc_call_t data;
185 if (!async_data_read_receive(&data, &data_len)) {
186 async_answer_0(icall, EPARTY);
[6cb58e6]187 return;
188 }
189
190 void *buffer = malloc(data_len);
191 if (buffer == NULL) {
[984a9ba]192 async_answer_0(icall, ENOMEM);
[6cb58e6]193 return;
194 }
195
196 size_t actual_len;
197 rc = usbvirt_data_in(dev, transfer_type, endpoint,
198 buffer, data_len, &actual_len);
199
200 if (rc != EOK) {
[984a9ba]201 async_answer_0(&data, rc);
202 async_answer_0(icall, rc);
[6cb58e6]203 free(buffer);
204 return;
205 }
206
[984a9ba]207 async_data_read_finalize(&data, buffer, actual_len);
208 async_answer_0(icall, EOK);
[6cb58e6]209
210 free(buffer);
211}
212
[beee81a]213/** Handle VHC request for data write to the device (out transfer).
214 *
[984a9ba]215 * @param dev Target virtual device.
[beee81a]216 * @param icall The call with the request.
[984a9ba]217 *
[beee81a]218 */
219static void ipc_data_out(usbvirt_device_t *dev,
[984a9ba]220 usb_transfer_type_t transfer_type, ipc_call_t *icall)
[6cb58e6]221{
[fafb8e5]222 usb_endpoint_t endpoint = ipc_get_arg1(icall);
[aa9a53d]223
224 void *data_buffer = NULL;
225 size_t data_buffer_size = 0;
226
[b7fd2a0]227 errno_t rc = async_data_write_accept(&data_buffer, false,
[beee81a]228 1, 0, 0, &data_buffer_size);
[aa9a53d]229 if (rc != EOK) {
[984a9ba]230 async_answer_0(icall, rc);
[aa9a53d]231 return;
232 }
233
234 rc = usbvirt_data_out(dev, transfer_type, endpoint,
235 data_buffer, data_buffer_size);
236
[984a9ba]237 async_answer_0(icall, rc);
[aa9a53d]238
239 free(data_buffer);
[6cb58e6]240}
241
[beee81a]242/** Handle incoming IPC call for virtual USB device.
243 *
[984a9ba]244 * @param dev Target USB device.
[beee81a]245 * @param call Incoming call.
[984a9ba]246 *
[beee81a]247 * @return Whether the call was handled.
[984a9ba]248 *
[beee81a]249 */
[984a9ba]250bool usbvirt_ipc_handle_call(usbvirt_device_t *dev, ipc_call_t *call)
[6cb58e6]251{
[fafb8e5]252 switch (ipc_get_imethod(call)) {
[beee81a]253 case IPC_M_USBVIRT_GET_NAME:
[984a9ba]254 ipc_get_name(dev, call);
[beee81a]255 break;
256
257 case IPC_M_USBVIRT_CONTROL_READ:
[984a9ba]258 ipc_control_read(dev, call);
[beee81a]259 break;
260
261 case IPC_M_USBVIRT_CONTROL_WRITE:
[984a9ba]262 ipc_control_write(dev, call);
[beee81a]263 break;
264
265 case IPC_M_USBVIRT_INTERRUPT_IN:
[984a9ba]266 ipc_data_in(dev, USB_TRANSFER_INTERRUPT, call);
[beee81a]267 break;
[6cb58e6]268
[beee81a]269 case IPC_M_USBVIRT_BULK_IN:
[984a9ba]270 ipc_data_in(dev, USB_TRANSFER_BULK, call);
[beee81a]271 break;
[6cb58e6]272
[beee81a]273 case IPC_M_USBVIRT_INTERRUPT_OUT:
[984a9ba]274 ipc_data_out(dev, USB_TRANSFER_INTERRUPT, call);
[beee81a]275 break;
[6cb58e6]276
[beee81a]277 case IPC_M_USBVIRT_BULK_OUT:
[984a9ba]278 ipc_data_out(dev, USB_TRANSFER_BULK, call);
[beee81a]279 break;
[6cb58e6]280
[beee81a]281 default:
282 return false;
[6cb58e6]283 }
284
285 return true;
286}
287
288/**
289 * @}
290 */
Note: See TracBrowser for help on using the repository browser.