Changes in uspace/lib/drv/generic/remote_usbhc.c [99172baf:41df71f9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhc.c
r99172baf r41df71f9 1 1 /* 2 * Copyright (c) 2010 -2011Vojtech Horky2 * Copyright (c) 2010 Vojtech Horky 3 3 * Copyright (c) 2011 Jan Vesely 4 * Copyright (c) 2017 Ondrej Hlavaty 4 5 * All rights reserved. 5 6 * … … 35 36 36 37 #include <async.h> 38 #include <macros.h> 37 39 #include <errno.h> 38 #include < assert.h>39 #include < macros.h>40 #include <devman.h> 41 #include <usb/host/usb_transfer_batch.h> 40 42 41 43 #include "usbhc_iface.h" 42 44 #include "ddf/driver.h" 43 45 44 #define USB_MAX_PAYLOAD_SIZE 1020 45 46 /** IPC methods for communication with HC through DDF interface. 47 * 48 * Notes for async methods: 49 * 50 * Methods for sending data to device (OUT transactions) 51 * - e.g. IPC_M_USBHC_INTERRUPT_OUT - 52 * always use the same semantics: 53 * - first, IPC call with given method is made 54 * - argument #1 is target address 55 * - argument #2 is target endpoint 56 * - argument #3 is max packet size of the endpoint 57 * - this call is immediately followed by IPC data write (from caller) 58 * - the initial call (and the whole transaction) is answer after the 59 * transaction is scheduled by the HC and acknowledged by the device 60 * or immediately after error is detected 61 * - the answer carries only the error code 62 * 63 * Methods for retrieving data from device (IN transactions) 64 * - e.g. IPC_M_USBHC_INTERRUPT_IN - 65 * also use the same semantics: 66 * - first, IPC call with given method is made 67 * - argument #1 is target address 68 * - argument #2 is target endpoint 69 * - this call is immediately followed by IPC data read (async version) 70 * - the call is not answered until the device returns some data (or until 71 * error occurs) 72 * 73 * Some special methods (NO-DATA transactions) do not send any data. These 74 * might behave as both OUT or IN transactions because communication parts 75 * where actual buffers are exchanged are omitted. 76 ** 77 * For all these methods, wrap functions exists. Important rule: functions 78 * for IN transactions have (as parameters) buffers where retrieved data 79 * will be stored. These buffers must be already allocated and shall not be 80 * touch until the transaction is completed 81 * (e.g. not before calling usb_wait_for() with appropriate handle). 82 * OUT transactions buffers can be freed immediately after call is dispatched 83 * (i.e. after return from wrapping function). 84 * 85 */ 46 86 47 typedef enum { 87 /** Asks for address assignment by host controller. 88 * Answer: 89 * - ELIMIT - host controller run out of address 90 * - EOK - address assigned 91 * Answer arguments: 92 * - assigned address 93 * 94 * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS. 95 */ 96 IPC_M_USBHC_REQUEST_ADDRESS, 97 98 /** Bind USB address with devman handle. 99 * Parameters: 100 * - USB address 101 * - devman handle 102 * Answer: 103 * - EOK - address binded 104 * - ENOENT - address is not in use 105 */ 106 IPC_M_USBHC_BIND_ADDRESS, 107 108 /** Get handle binded with given USB address. 109 * Parameters 110 * - USB address 111 * Answer: 112 * - EOK - address binded, first parameter is the devman handle 113 * - ENOENT - address is not in use at the moment 114 */ 115 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, 116 117 /** Release address in use. 118 * Arguments: 119 * - address to be released 120 * Answer: 121 * - ENOENT - address not in use 122 * - EPERM - trying to release default USB address 123 */ 124 IPC_M_USBHC_RELEASE_ADDRESS, 125 126 /** Register endpoint attributes at host controller. 127 * This is used to reserve portion of USB bandwidth. 128 * When speed is invalid, speed of the device is used. 129 * Parameters: 130 * - USB address + endpoint number 131 * - packed as ADDR << 16 + EP 132 * - speed + transfer type + direction 133 * - packed as ( SPEED << 8 + TYPE ) << 8 + DIR 134 * - maximum packet size + interval (in milliseconds) 135 * - packed as MPS << 16 + INT 136 * Answer: 137 * - EOK - reservation successful 138 * - ELIMIT - not enough bandwidth to satisfy the request 139 */ 140 IPC_M_USBHC_REGISTER_ENDPOINT, 141 142 /** Revert endpoint registration. 143 * Parameters: 144 * - USB address 145 * - endpoint number 146 * - data direction 147 * Answer: 148 * - EOK - endpoint unregistered 149 * - ENOENT - unknown endpoint 150 */ 151 IPC_M_USBHC_UNREGISTER_ENDPOINT, 152 153 /** Get data from device. 154 * See explanation at usb_iface_funcs_t (IN transaction). 155 */ 156 IPC_M_USBHC_READ, 157 158 /** Send data to device. 159 * See explanation at usb_iface_funcs_t (OUT transaction). 160 */ 161 IPC_M_USBHC_WRITE, 48 IPC_M_USB_RESERVE_DEFAULT_ADDRESS, 49 IPC_M_USB_RELEASE_DEFAULT_ADDRESS, 50 IPC_M_USB_DEVICE_ENUMERATE, 51 IPC_M_USB_DEVICE_REMOVE, 52 IPC_M_USB_REGISTER_ENDPOINT, 53 IPC_M_USB_UNREGISTER_ENDPOINT, 54 IPC_M_USB_READ, 55 IPC_M_USB_WRITE, 162 56 } usbhc_iface_funcs_t; 163 57 164 int usbhc_request_address(async_exch_t *exch, usb_address_t *address, 165 bool strict, usb_speed_t speed) 166 { 167 if (!exch || !address) 168 return EBADMEM; 169 sysarg_t new_address; 170 const int ret = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 171 IPC_M_USBHC_REQUEST_ADDRESS, *address, strict, speed, &new_address); 172 if (ret == EOK) 173 *address = (usb_address_t)new_address; 58 /** Reserve default USB address. 59 * @param[in] exch IPC communication exchange 60 * @param[in] speed Communication speed of the newly attached device 61 * @return Error code. 62 */ 63 int usbhc_reserve_default_address(async_exch_t *exch, usb_speed_t speed) 64 { 65 if (!exch) 66 return EBADMEM; 67 return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 68 IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed); 69 } 70 71 /** Release default USB address. 72 * 73 * @param[in] exch IPC communication exchange 74 * 75 * @return Error code. 76 * 77 */ 78 int usbhc_release_default_address(async_exch_t *exch) 79 { 80 if (!exch) 81 return EBADMEM; 82 return async_req_1_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 83 IPC_M_USB_RELEASE_DEFAULT_ADDRESS); 84 } 85 86 /** Trigger USB device enumeration 87 * 88 * @param[in] exch IPC communication exchange 89 * @param[out] handle Identifier of the newly added device (if successful) 90 * 91 * @return Error code. 92 * 93 */ 94 int usbhc_device_enumerate(async_exch_t *exch, unsigned port) 95 { 96 if (!exch) 97 return EBADMEM; 98 const int ret = async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 99 IPC_M_USB_DEVICE_ENUMERATE, port); 174 100 return ret; 175 101 } 176 102 177 int usbhc_bind_address(async_exch_t *exch, usb_address_t address, 178 devman_handle_t handle) 179 { 180 if (!exch) 181 return EBADMEM; 182 return async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 183 IPC_M_USBHC_BIND_ADDRESS, address, handle); 184 } 185 186 int usbhc_get_handle(async_exch_t *exch, usb_address_t address, 187 devman_handle_t *handle) 188 { 189 if (!exch) 190 return EBADMEM; 191 sysarg_t h; 192 const int ret = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 193 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, address, &h); 194 if (ret == EOK && handle) 195 *handle = (devman_handle_t)h; 196 return ret; 197 } 198 199 int usbhc_release_address(async_exch_t *exch, usb_address_t address) 103 /** Trigger USB device enumeration 104 * 105 * @param[in] exch IPC communication exchange 106 * @param[in] handle Identifier of the device 107 * 108 * @return Error code. 109 * 110 */ 111 int usbhc_device_remove(async_exch_t *exch, unsigned port) 200 112 { 201 113 if (!exch) 202 114 return EBADMEM; 203 115 return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 204 IPC_M_USBHC_RELEASE_ADDRESS, address); 205 } 206 207 int usbhc_register_endpoint(async_exch_t *exch, usb_address_t address, 208 usb_endpoint_t endpoint, usb_transfer_type_t type, 209 usb_direction_t direction, size_t mps, unsigned interval) 210 { 211 if (!exch) 212 return EBADMEM; 213 const usb_target_t target = 214 {{ .address = address, .endpoint = endpoint }}; 215 #define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff)) 216 217 return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 218 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed, 219 _PACK2(type, direction), _PACK2(mps, interval)); 220 221 #undef _PACK2 222 } 223 224 int usbhc_unregister_endpoint(async_exch_t *exch, usb_address_t address, 225 usb_endpoint_t endpoint, usb_direction_t direction) 226 { 227 if (!exch) 228 return EBADMEM; 229 return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 230 IPC_M_USBHC_UNREGISTER_ENDPOINT, address, endpoint, direction); 231 } 232 233 int usbhc_read(async_exch_t *exch, usb_address_t address, 234 usb_endpoint_t endpoint, uint64_t setup, void *data, size_t size, 235 size_t *rec_size) 116 IPC_M_USB_DEVICE_REMOVE, port); 117 } 118 119 int static_assert[sizeof(sysarg_t) >= 4 ? 1 : -1]; 120 typedef union { 121 uint8_t arr[sizeof(sysarg_t)]; 122 sysarg_t arg; 123 } pack8_t; 124 125 int usbhc_register_endpoint(async_exch_t *exch, 126 usb_endpoint_desc_t *endpoint_desc) 127 { 128 if (!exch) 129 return EBADMEM; 130 131 aid_t opening_request = async_send_1(exch, 132 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_REGISTER_ENDPOINT, NULL); 133 134 if (opening_request == 0) { 135 return ENOMEM; 136 } 137 138 const int ret = async_data_write_start(exch, (void *) endpoint_desc, 139 sizeof(usb_endpoint_desc_t)); 140 141 if (ret != EOK) { 142 async_forget(opening_request); 143 return ret; 144 } 145 146 /* Wait for the answer. */ 147 sysarg_t opening_request_rc; 148 async_wait_for(opening_request, &opening_request_rc); 149 150 return (int) opening_request_rc; 151 } 152 153 int usbhc_unregister_endpoint(async_exch_t *exch, 154 usb_endpoint_desc_t *endpoint_desc) 155 { 156 if (!exch) 157 return EBADMEM; 158 159 aid_t opening_request = async_send_1(exch, 160 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_UNREGISTER_ENDPOINT, NULL); 161 162 if (opening_request == 0) { 163 return ENOMEM; 164 } 165 166 const int ret = async_data_write_start(exch, endpoint_desc, 167 sizeof(usb_endpoint_desc_t)); 168 if (ret != EOK) { 169 async_forget(opening_request); 170 return ret; 171 } 172 173 /* Wait for the answer. */ 174 sysarg_t opening_request_rc; 175 async_wait_for(opening_request, &opening_request_rc); 176 177 return (int) opening_request_rc; 178 } 179 180 int usbhc_read(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup, 181 void *data, size_t size, size_t *rec_size) 236 182 { 237 183 if (!exch) … … 241 187 return EOK; 242 188 243 const usb_target_t target =244 {{ .address = address, .endpoint = endpoint }};245 246 189 /* Make call identifying target USB device and type of transfer. */ 247 190 aid_t opening_request = async_send_4(exch, 248 DEV_IFACE_ID(USBHC_DEV_IFACE), 249 IPC_M_USBHC_READ, target.packed, 191 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_READ, endpoint, 250 192 (setup & UINT32_MAX), (setup >> 32), NULL); 251 193 … … 287 229 } 288 230 289 int usbhc_write(async_exch_t *exch, usb_ address_t address,290 usb_endpoint_t endpoint, uint64_t setup,const void *data, size_t size)231 int usbhc_write(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup, 232 const void *data, size_t size) 291 233 { 292 234 if (!exch) … … 296 238 return EOK; 297 239 298 const usb_target_t target = 299 {{ .address = address, .endpoint = endpoint }}; 300 301 aid_t opening_request = async_send_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 302 IPC_M_USBHC_WRITE, target.packed, size, 240 aid_t opening_request = async_send_5(exch, 241 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_WRITE, endpoint, size, 303 242 (setup & UINT32_MAX), (setup >> 32), NULL); 304 243 … … 323 262 } 324 263 325 326 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 327 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 328 static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 329 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 264 static void remote_usbhc_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 265 static void remote_usbhc_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 266 static void remote_usbhc_device_enumerate(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 267 static void remote_usbhc_device_remove(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 330 268 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 331 269 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 332 static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 333 static void remote_usbhc_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 334 //static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 335 336 /** Remote USB host controller interface operations. */ 337 static const remote_iface_func_ptr_t remote_usbhc_iface_ops[] = { 338 [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address, 339 [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address, 340 [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address, 341 [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_get_handle, 342 343 [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint, 344 [IPC_M_USBHC_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint, 345 346 [IPC_M_USBHC_READ] = remote_usbhc_read, 347 [IPC_M_USBHC_WRITE] = remote_usbhc_write, 270 static void remote_usbhc_read(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call); 271 static void remote_usbhc_write(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call); 272 273 /** Remote USB interface operations. */ 274 static const remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 275 [IPC_M_USB_RESERVE_DEFAULT_ADDRESS] = remote_usbhc_reserve_default_address, 276 [IPC_M_USB_RELEASE_DEFAULT_ADDRESS] = remote_usbhc_release_default_address, 277 [IPC_M_USB_DEVICE_ENUMERATE] = remote_usbhc_device_enumerate, 278 [IPC_M_USB_DEVICE_REMOVE] = remote_usbhc_device_remove, 279 [IPC_M_USB_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint, 280 [IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint, 281 [IPC_M_USB_READ] = remote_usbhc_read, 282 [IPC_M_USB_WRITE] = remote_usbhc_write, 348 283 }; 349 284 350 /** Remote USB host controllerinterface structure.285 /** Remote USB interface structure. 351 286 */ 352 287 const remote_iface_t remote_usbhc_iface = { 353 288 .method_count = ARRAY_SIZE(remote_usbhc_iface_ops), 354 .methods = remote_usbhc_iface_ops 289 .methods = remote_usbhc_iface_ops, 355 290 }; 356 291 … … 361 296 } async_transaction_t; 362 297 298 void remote_usbhc_reserve_default_address(ddf_fun_t *fun, void *iface, 299 ipc_callid_t callid, ipc_call_t *call) 300 { 301 const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface; 302 303 if (usbhc_iface->reserve_default_address == NULL) { 304 async_answer_0(callid, ENOTSUP); 305 return; 306 } 307 308 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 309 const int ret = usbhc_iface->reserve_default_address(fun, speed); 310 async_answer_0(callid, ret); 311 } 312 313 void remote_usbhc_release_default_address(ddf_fun_t *fun, void *iface, 314 ipc_callid_t callid, ipc_call_t *call) 315 { 316 const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface; 317 318 if (usbhc_iface->release_default_address == NULL) { 319 async_answer_0(callid, ENOTSUP); 320 return; 321 } 322 323 const int ret = usbhc_iface->release_default_address(fun); 324 async_answer_0(callid, ret); 325 } 326 327 static void remote_usbhc_device_enumerate(ddf_fun_t *fun, void *iface, 328 ipc_callid_t callid, ipc_call_t *call) 329 { 330 const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface; 331 332 if (usbhc_iface->device_enumerate == NULL) { 333 async_answer_0(callid, ENOTSUP); 334 return; 335 } 336 337 const unsigned port = DEV_IPC_GET_ARG1(*call); 338 const int ret = usbhc_iface->device_enumerate(fun, port); 339 async_answer_0(callid, ret); 340 } 341 342 static void remote_usbhc_device_remove(ddf_fun_t *fun, void *iface, 343 ipc_callid_t callid, ipc_call_t *call) 344 { 345 const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface; 346 347 if (usbhc_iface->device_remove == NULL) { 348 async_answer_0(callid, ENOTSUP); 349 return; 350 } 351 352 const unsigned port = DEV_IPC_GET_ARG1(*call); 353 const int ret = usbhc_iface->device_remove(fun, port); 354 async_answer_0(callid, ret); 355 } 356 357 static void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface, 358 ipc_callid_t callid, ipc_call_t *call) 359 { 360 assert(fun); 361 assert(iface); 362 assert(call); 363 364 const usbhc_iface_t *usbhc_iface = iface; 365 366 if (!usbhc_iface->register_endpoint) { 367 async_answer_0(callid, ENOTSUP); 368 return; 369 } 370 371 void *buffer = NULL; 372 size_t size = 0; 373 int rc = async_data_write_accept(&buffer, false, 374 sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size); 375 376 if (rc != EOK) { 377 free(buffer); 378 async_answer_0(callid, rc); 379 return; 380 } 381 382 usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer; 383 rc = usbhc_iface->register_endpoint(fun, endpoint_desc); 384 385 free(buffer); 386 async_answer_0(callid, rc); 387 } 388 389 static void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface, 390 ipc_callid_t callid, ipc_call_t *call) 391 { 392 assert(fun); 393 assert(iface); 394 assert(call); 395 396 const usbhc_iface_t *usbhc_iface = iface; 397 398 if (!usbhc_iface->unregister_endpoint) { 399 async_answer_0(callid, ENOTSUP); 400 return; 401 } 402 403 void *buffer = NULL; 404 size_t size = 0; 405 int rc = async_data_write_accept(&buffer, false, 406 sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size); 407 408 if (rc != EOK) { 409 free(buffer); 410 async_answer_0(callid, rc); 411 return; 412 } 413 414 usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer; 415 usbhc_iface->unregister_endpoint(fun, endpoint_desc); 416 417 free(buffer); 418 async_answer_0(callid, rc); 419 } 420 363 421 static void async_transaction_destroy(async_transaction_t *trans) 364 422 { 365 if (trans == NULL) 366 return; 367 368 if (trans->buffer != NULL) 423 if (trans == NULL) { 424 return; 425 } 426 if (trans->buffer != NULL) { 369 427 free(trans->buffer); 370 428 } 429 371 430 free(trans); 372 431 } … … 386 445 } 387 446 388 void remote_usbhc_request_address(ddf_fun_t *fun, void *iface, 389 ipc_callid_t callid, ipc_call_t *call) 390 { 391 const usbhc_iface_t *usb_iface = iface; 392 393 if (!usb_iface->request_address) { 394 async_answer_0(callid, ENOTSUP); 395 return; 396 } 397 398 usb_address_t address = DEV_IPC_GET_ARG1(*call); 399 const bool strict = DEV_IPC_GET_ARG2(*call); 400 const usb_speed_t speed = DEV_IPC_GET_ARG3(*call); 401 402 const int rc = usb_iface->request_address(fun, &address, strict, speed); 403 if (rc != EOK) { 404 async_answer_0(callid, rc); 405 } else { 406 async_answer_1(callid, EOK, (sysarg_t) address); 407 } 408 } 409 410 void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface, 411 ipc_callid_t callid, ipc_call_t *call) 412 { 413 const usbhc_iface_t *usb_iface = iface; 414 415 if (!usb_iface->bind_address) { 416 async_answer_0(callid, ENOTSUP); 417 return; 418 } 419 420 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 421 const devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call); 422 423 const int ret = usb_iface->bind_address(fun, address, handle); 424 async_answer_0(callid, ret); 425 } 426 427 void remote_usbhc_get_handle(ddf_fun_t *fun, void *iface, 428 ipc_callid_t callid, ipc_call_t *call) 429 { 430 const usbhc_iface_t *usb_iface = iface; 431 432 if (!usb_iface->get_handle) { 433 async_answer_0(callid, ENOTSUP); 434 return; 435 } 436 437 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 438 devman_handle_t handle; 439 const int ret = usb_iface->get_handle(fun, address, &handle); 440 441 if (ret == EOK) { 442 async_answer_1(callid, ret, handle); 443 } else { 444 async_answer_0(callid, ret); 445 } 446 } 447 448 void remote_usbhc_release_address(ddf_fun_t *fun, void *iface, 449 ipc_callid_t callid, ipc_call_t *call) 450 { 451 const usbhc_iface_t *usb_iface = iface; 452 453 if (!usb_iface->release_address) { 454 async_answer_0(callid, ENOTSUP); 455 return; 456 } 457 458 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 459 460 const int ret = usb_iface->release_address(fun, address); 461 async_answer_0(callid, ret); 462 } 463 464 static void callback_out(ddf_fun_t *fun, 465 int outcome, void *arg) 466 { 467 async_transaction_t *trans = arg; 468 469 async_answer_0(trans->caller, outcome); 447 static int callback_out(usb_transfer_batch_t *batch) 448 { 449 async_transaction_t *trans = batch->on_complete_data; 450 451 const int err = async_answer_0(trans->caller, batch->error); 470 452 471 453 async_transaction_destroy(trans); 472 } 473 474 static void callback_in(ddf_fun_t *fun, 475 int outcome, size_t actual_size, void *arg) 476 { 477 async_transaction_t *trans = (async_transaction_t *)arg; 478 479 if (outcome != EOK) { 480 async_answer_0(trans->caller, outcome); 481 if (trans->data_caller) { 454 455 return err; 456 } 457 458 static int callback_in(usb_transfer_batch_t *batch) 459 { 460 async_transaction_t *trans = batch->on_complete_data; 461 462 if (trans->data_caller) { 463 if (batch->error == EOK) { 464 batch->error = async_data_read_finalize(trans->data_caller, 465 trans->buffer, batch->transfered_size); 466 } else { 482 467 async_answer_0(trans->data_caller, EINTR); 483 468 } 484 async_transaction_destroy(trans); 485 return; 486 } 487 488 if (trans->data_caller) { 489 async_data_read_finalize(trans->data_caller, 490 trans->buffer, actual_size); 491 } 492 493 async_answer_0(trans->caller, EOK); 494 469 } 470 471 const int err = async_answer_0(trans->caller, batch->error); 495 472 async_transaction_destroy(trans); 496 } 497 498 void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface, 499 ipc_callid_t callid, ipc_call_t *call) 500 { 501 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 502 503 if (!usb_iface->register_endpoint) { 504 async_answer_0(callid, ENOTSUP); 505 return; 506 } 507 508 #define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \ 509 type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16) 510 #define _INIT_FROM_LOW_DATA2(type, var, arg_no) \ 511 type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff) 512 513 const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) }; 514 515 _INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2); 516 _INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2); 517 518 _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3); 519 _INIT_FROM_LOW_DATA2(unsigned int, interval, 3); 520 521 #undef _INIT_FROM_HIGH_DATA2 522 #undef _INIT_FROM_LOW_DATA2 523 524 int rc = usb_iface->register_endpoint(fun, target.address, 525 target.endpoint, transfer_type, direction, max_packet_size, interval); 526 527 async_answer_0(callid, rc); 528 } 529 530 void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface, 531 ipc_callid_t callid, ipc_call_t *call) 532 { 533 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 534 535 if (!usb_iface->unregister_endpoint) { 536 async_answer_0(callid, ENOTSUP); 537 return; 538 } 539 540 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 541 usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call); 542 usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call); 543 544 int rc = usb_iface->unregister_endpoint(fun, 545 address, endpoint, direction); 546 547 async_answer_0(callid, rc); 473 return err; 548 474 } 549 475 … … 555 481 assert(call); 556 482 557 const usbhc_iface_t * hc_iface = iface;558 559 if (! hc_iface->read) {560 async_answer_0(callid, ENOTSUP); 561 return; 562 } 563 564 const usb_ target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };483 const usbhc_iface_t *usbhc_iface = iface; 484 485 if (!usbhc_iface->read) { 486 async_answer_0(callid, ENOTSUP); 487 return; 488 } 489 490 const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call); 565 491 const uint64_t setup = 566 492 ((uint64_t)DEV_IPC_GET_ARG2(*call)) | … … 576 502 if (!async_data_read_receive(&trans->data_caller, &size)) { 577 503 async_answer_0(callid, EPARTY); 504 async_transaction_destroy(trans); 578 505 return; 579 506 } … … 587 514 } 588 515 589 const int rc = hc_iface->read( 516 const usb_target_t target = {{ 517 /* .address is initialized by read itself */ 518 .endpoint = ep, 519 }}; 520 521 const int rc = usbhc_iface->read( 590 522 fun, target, setup, trans->buffer, size, callback_in, trans); 591 523 … … 604 536 assert(call); 605 537 606 const usbhc_iface_t * hc_iface = iface;607 608 if (! hc_iface->write) {609 async_answer_0(callid, ENOTSUP); 610 return; 611 } 612 613 const usb_ target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };538 const usbhc_iface_t *usbhc_iface = iface; 539 540 if (!usbhc_iface->write) { 541 async_answer_0(callid, ENOTSUP); 542 return; 543 } 544 545 const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call); 614 546 const size_t data_buffer_len = DEV_IPC_GET_ARG2(*call); 615 547 const uint64_t setup = … … 626 558 if (data_buffer_len > 0) { 627 559 const int rc = async_data_write_accept(&trans->buffer, false, 628 1, USB_MAX_PAYLOAD_SIZE, 629 0, &size); 560 1, data_buffer_len, 0, &size); 630 561 631 562 if (rc != EOK) { … … 636 567 } 637 568 638 const int rc = hc_iface->write( 569 const usb_target_t target = {{ 570 /* .address is initialized by write itself */ 571 .endpoint = ep, 572 }}; 573 574 const int rc = usbhc_iface->write( 639 575 fun, target, setup, trans->buffer, size, callback_out, trans); 640 576
Note:
See TracChangeset
for help on using the changeset viewer.