Changeset 239eea41 in mainline for uspace/lib/drv/generic/remote_usbhc.c
- Timestamp:
- 2018-02-05T02:04:58Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fc3dfe6d
- Parents:
- af16ebe
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhc.c
raf16ebe r239eea41 51 51 IPC_M_USB_REGISTER_ENDPOINT, 52 52 IPC_M_USB_UNREGISTER_ENDPOINT, 53 IPC_M_USB_READ, 54 IPC_M_USB_WRITE, 53 IPC_M_USB_TRANSFER, 55 54 } usbhc_iface_funcs_t; 56 55 … … 183 182 * temporarily shared with the HC. 184 183 */ 185 errno_t usbhc_transfer(async_exch_t *exch, usb_endpoint_t endpoint, 186 usb_direction_t dir, uint64_t setup, void *area, size_t size, 187 size_t *transferred) 184 errno_t usbhc_transfer(async_exch_t *exch, 185 const usbhc_iface_transfer_request_t *req, size_t *transferred) 188 186 { 189 187 if (transferred) … … 193 191 return EBADMEM; 194 192 195 if (size == 0 && setup == 0)196 return EOK;197 198 sysarg_t method = (dir == USB_DIRECTION_IN)199 ? IPC_M_USB_READ : IPC_M_USB_WRITE;200 201 193 ipc_call_t call; 202 194 203 204 aid_t opening_request = async_send_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 205 method, endpoint, size, (setup & UINT32_MAX), (setup >> 32), &call); 195 aid_t opening_request = async_send_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 196 IPC_M_USB_TRANSFER, &call); 206 197 207 198 if (opening_request == 0) 208 199 return ENOMEM; 209 200 210 /* Send the data if any. */ 211 if (size > 0) { 212 unsigned flags = (dir == USB_DIRECTION_IN) 201 const errno_t ret = async_data_write_start(exch, req, sizeof(*req)); 202 if (ret != EOK) { 203 async_forget(opening_request); 204 return ret; 205 } 206 207 /* Share the data, if any. */ 208 if (req->size > 0) { 209 unsigned flags = (req->dir == USB_DIRECTION_IN) 213 210 ? AS_AREA_WRITE : AS_AREA_READ; 214 211 215 const errno_t ret = async_share_out_start(exch, area, flags);212 const errno_t ret = async_share_out_start(exch, req->base, flags); 216 213 if (ret != EOK) { 217 214 async_forget(opening_request); … … 244 241 [IPC_M_USB_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint, 245 242 [IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint, 246 [IPC_M_USB_READ] = remote_usbhc_transfer, 247 [IPC_M_USB_WRITE] = remote_usbhc_transfer, 243 [IPC_M_USB_TRANSFER] = remote_usbhc_transfer, 248 244 }; 249 245 … … 257 253 typedef struct { 258 254 ipc_callid_t caller; 259 void *buffer;255 usbhc_iface_transfer_request_t request; 260 256 } async_transaction_t; 261 257 … … 378 374 return; 379 375 } 380 if (trans-> buffer!= NULL) {381 as_area_destroy(trans-> buffer);376 if (trans->request.base != NULL) { 377 as_area_destroy(trans->request.base); 382 378 } 383 379 … … 387 383 static async_transaction_t *async_transaction_create(ipc_callid_t caller) 388 384 { 389 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 390 if (trans == NULL) { 391 return NULL; 392 } 393 394 trans->caller = caller; 395 trans->buffer = NULL; 385 async_transaction_t *trans = calloc(1, sizeof(async_transaction_t)); 386 387 if (trans != NULL) 388 trans->caller = caller; 396 389 397 390 return trans; … … 406 399 } 407 400 408 static errno_t receive_memory_buffer(async_transaction_t *trans, 409 size_t required_size, unsigned required_flags) 401 static errno_t receive_memory_buffer(async_transaction_t *trans) 410 402 { 411 403 assert(trans); 412 assert(required_size > 0); 404 assert(trans->request.size > 0); 405 406 const size_t required_size = trans->request.offset + trans->request.size; 407 const unsigned required_flags = 408 (trans->request.dir == USB_DIRECTION_IN) 409 ? AS_AREA_WRITE : AS_AREA_READ; 413 410 414 411 errno_t err; … … 425 422 } 426 423 427 if ((err = async_share_out_finalize(data_callid, &trans-> buffer)))424 if ((err = async_share_out_finalize(data_callid, &trans->request.base))) 428 425 return err; 429 426 … … 435 432 if (flags & AS_AREA_READ) { 436 433 char foo = 0; 437 volatile const char *buf = trans-> buffer;434 volatile const char *buf = trans->request.base + trans->request.offset; 438 435 for (size_t i = 0; i < size; i += PAGE_SIZE) 439 436 foo += buf[i]; 440 437 } else { 441 volatile char *buf = trans-> buffer;438 volatile char *buf = trans->request.base + trans->request.offset; 442 439 for (size_t i = 0; i < size; i += PAGE_SIZE) 443 440 buf[i] = 0xff; … … 460 457 } 461 458 462 const sysarg_t method = IPC_GET_ARG1(*call);463 const usb_direction_t dir =464 method == IPC_M_USB_READ ? USB_DIRECTION_IN : USB_DIRECTION_OUT;465 466 const usb_endpoint_t ep = IPC_GET_ARG2(*call);467 const size_t size = IPC_GET_ARG3(*call);468 const uint64_t setup = ((uint64_t)IPC_GET_ARG4(*call)) |469 (((uint64_t)IPC_GET_ARG5(*call)) << 32);470 471 459 async_transaction_t *trans = async_transaction_create(callid); 472 460 if (trans == NULL) { … … 475 463 } 476 464 477 if (size > 0) { 478 const unsigned required_flags = (dir == USB_DIRECTION_IN) 479 ? AS_AREA_WRITE : AS_AREA_READ; 480 481 const errno_t rc = receive_memory_buffer(trans, size, required_flags); 482 if (rc != EOK) { 483 async_transaction_destroy(trans); 484 async_answer_0(callid, rc); 485 return; 486 } 487 } 488 489 const usb_target_t target = {{ 490 /* .address is initialized by write itself */ 491 .endpoint = ep, 492 /* streams are not given by the API call yet */ 493 .stream = 0, 494 }}; 495 496 const errno_t rc = usbhc_iface->transfer(fun, target, dir, setup, 497 trans->buffer, size, &transfer_finished, trans); 498 499 if (rc != EOK) { 500 async_answer_0(callid, rc); 501 async_transaction_destroy(trans); 502 } 465 errno_t err = EPARTY; 466 467 ipc_callid_t data_callid; 468 size_t len; 469 if (!async_data_write_receive(&data_callid, &len) 470 || len != sizeof(trans->request)) { 471 async_answer_0(data_callid, EINVAL); 472 goto err; 473 } 474 475 if ((err = async_data_write_finalize(data_callid, 476 &trans->request, sizeof(trans->request)))) 477 goto err; 478 479 if (trans->request.size > 0) { 480 if ((err = receive_memory_buffer(trans))) 481 goto err; 482 } else { 483 /* The value was valid on the other side, for us, its garbage. */ 484 trans->request.base = NULL; 485 } 486 487 if ((err = usbhc_iface->transfer(fun, &trans->request, 488 &transfer_finished, trans))) 489 goto err; 490 491 /* The call will be answered asynchronously by the callback. */ 492 return; 493 494 err: 495 async_answer_0(callid, err); 496 async_transaction_destroy(trans); 503 497 } 504 498
Note:
See TracChangeset
for help on using the changeset viewer.