Changeset 2185776 in mainline for uspace/lib/usb/hcd.c
- Timestamp:
- 2010-10-26T13:47:46Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 56cb9bd
- Parents:
- 23cb44b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/hcd.c
r23cb44b r2185776 35 35 #include "hcd.h" 36 36 #include <devmap.h> 37 #include <stdlib.h> 37 38 #include <fcntl.h> 38 39 #include <vfs/vfs.h> 39 40 #include <errno.h> 40 41 42 typedef struct { 43 int phone; 44 void *buffer; 45 size_t size; 46 size_t *size_transferred; 47 ipc_call_t reply; 48 aid_t request; 49 } transfer_info_t; 41 50 42 51 #define NAMESPACE "usb" … … 339 348 340 349 350 351 352 /* 353 * ================= 354 * async versions of the above functions 355 * ================= 356 */ 357 358 static int async_send_buffer(int phone, int method, 359 usb_target_t target, 360 void *buffer, size_t size, 361 usb_handle_t *handle) 362 { 363 if (phone < 0) { 364 return EINVAL; 365 } 366 367 if ((buffer == NULL) && (size > 0)) { 368 return EINVAL; 369 } 370 371 if (handle == NULL) { 372 return EINVAL; 373 } 374 375 transfer_info_t *transfer 376 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 377 if (transfer == NULL) { 378 return ENOMEM; 379 } 380 381 transfer->size_transferred = NULL; 382 transfer->buffer = NULL; 383 transfer->size = 0; 384 transfer->phone = phone; 385 386 int rc; 387 388 transfer->request = async_send_3(phone, 389 method, 390 target.address, target.endpoint, 391 size, 392 &transfer->reply); 393 394 if (size > 0) { 395 rc = async_data_write_start(phone, buffer, size); 396 if (rc != EOK) { 397 async_wait_for(transfer->request, NULL); 398 return rc; 399 } 400 } 401 402 *handle = (usb_handle_t) transfer; 403 404 return EOK; 405 } 406 407 static int async_recv_buffer(int phone, int method, 408 usb_target_t target, 409 void *buffer, size_t size, size_t *actual_size, 410 usb_handle_t *handle) 411 { 412 if (phone < 0) { 413 return EINVAL; 414 } 415 416 if ((buffer == NULL) && (size > 0)) { 417 return EINVAL; 418 } 419 420 if (handle == NULL) { 421 return EINVAL; 422 } 423 424 transfer_info_t *transfer 425 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 426 if (transfer == NULL) { 427 return ENOMEM; 428 } 429 430 transfer->size_transferred = actual_size; 431 transfer->buffer = buffer; 432 transfer->size = size; 433 transfer->phone = phone; 434 435 transfer->request = async_send_3(phone, 436 method, 437 target.address, target.endpoint, 438 size, 439 &transfer->reply); 440 441 *handle = (usb_handle_t) transfer; 442 443 return EOK; 444 } 445 446 static int read_buffer_in(int phone, ipcarg_t hash, 447 void *buffer, size_t size, size_t *actual_size) 448 { 449 ipc_call_t answer_data; 450 ipcarg_t answer_rc; 451 aid_t req; 452 int rc; 453 454 req = async_send_1(phone, 455 IPC_M_USB_HCD_GET_BUFFER_ASYNC, 456 hash, 457 &answer_data); 458 459 rc = async_data_read_start(phone, buffer, size); 460 if (rc != EOK) { 461 async_wait_for(req, NULL); 462 return EINVAL; 463 } 464 465 async_wait_for(req, &answer_rc); 466 rc = (int)answer_rc; 467 468 if (rc != EOK) { 469 return rc; 470 } 471 472 *actual_size = IPC_GET_ARG1(answer_data); 473 474 return EOK; 475 } 476 477 478 int usb_hcd_async_wait_for(usb_handle_t handle) 479 { 480 if (handle == 0) { 481 return EBADMEM; 482 } 483 484 int rc = EOK; 485 486 transfer_info_t *transfer = (transfer_info_t *) handle; 487 488 ipcarg_t answer_rc; 489 async_wait_for(transfer->request, &answer_rc); 490 491 if (answer_rc != EOK) { 492 rc = (int) answer_rc; 493 goto leave; 494 } 495 496 /* 497 * If the buffer is not NULL, we must accept some data. 498 */ 499 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 500 /* 501 * The buffer hash identifies the data on the server 502 * side. 503 * We will use it when actually reading-in the data. 504 */ 505 ipcarg_t buffer_hash = IPC_GET_ARG1(transfer->reply); 506 if (buffer_hash == 0) { 507 rc = ENOENT; 508 goto leave; 509 } 510 511 size_t actual_size; 512 rc = read_buffer_in(transfer->phone, buffer_hash, 513 transfer->buffer, transfer->size, &actual_size); 514 515 if (rc != EOK) { 516 goto leave; 517 } 518 519 if (transfer->size_transferred) { 520 *(transfer->size_transferred) = actual_size; 521 } 522 } 523 524 leave: 525 free(transfer); 526 527 return rc; 528 } 529 530 int usb_hcd_async_transfer_interrupt_out(int hcd_phone, 531 usb_target_t target, 532 void *buffer, size_t size, 533 usb_handle_t *handle) 534 { 535 return async_send_buffer(hcd_phone, 536 IPC_M_USB_HCD_INTERRUPT_OUT_ASYNC, 537 target, 538 buffer, size, 539 handle); 540 } 541 542 int usb_hcd_async_transfer_interrupt_in(int hcd_phone, 543 usb_target_t target, 544 void *buffer, size_t size, size_t *actual_size, 545 usb_handle_t *handle) 546 { 547 return async_recv_buffer(hcd_phone, 548 IPC_M_USB_HCD_INTERRUPT_IN_ASYNC, 549 target, 550 buffer, size, actual_size, 551 handle); 552 } 553 554 int usb_hcd_async_transfer_control_write_setup(int hcd_phone, 555 usb_target_t target, 556 void *buffer, size_t size, 557 usb_handle_t *handle) 558 { 559 return async_send_buffer(hcd_phone, 560 IPC_M_USB_HCD_CONTROL_WRITE_SETUP_ASYNC, 561 target, 562 buffer, size, 563 handle); 564 } 565 566 int usb_hcd_async_transfer_control_write_data(int hcd_phone, 567 usb_target_t target, 568 void *buffer, size_t size, 569 usb_handle_t *handle) 570 { 571 return async_send_buffer(hcd_phone, 572 IPC_M_USB_HCD_CONTROL_WRITE_DATA_ASYNC, 573 target, 574 buffer, size, 575 handle); 576 } 577 578 int usb_hcd_async_transfer_control_write_status(int hcd_phone, 579 usb_target_t target, 580 usb_handle_t *handle) 581 { 582 return async_recv_buffer(hcd_phone, 583 IPC_M_USB_HCD_CONTROL_WRITE_STATUS_ASYNC, 584 target, 585 NULL, 0, NULL, 586 handle); 587 } 588 589 int usb_hcd_async_transfer_control_read_setup(int hcd_phone, 590 usb_target_t target, 591 void *buffer, size_t size, 592 usb_handle_t *handle) 593 { 594 return async_send_buffer(hcd_phone, 595 IPC_M_USB_HCD_CONTROL_READ_SETUP_ASYNC, 596 target, 597 buffer, size, 598 handle); 599 } 600 601 int usb_hcd_async_transfer_control_read_data(int hcd_phone, 602 usb_target_t target, 603 void *buffer, size_t size, size_t *actual_size, 604 usb_handle_t *handle) 605 { 606 return async_recv_buffer(hcd_phone, 607 IPC_M_USB_HCD_CONTROL_READ_DATA_ASYNC, 608 target, 609 buffer, size, actual_size, 610 handle); 611 } 612 613 int usb_hcd_async_transfer_control_read_status(int hcd_phone, 614 usb_target_t target, 615 usb_handle_t *handle) 616 { 617 return async_send_buffer(hcd_phone, 618 IPC_M_USB_HCD_CONTROL_READ_STATUS_ASYNC, 619 target, 620 NULL, 0, 621 handle); 622 } 623 341 624 /** 342 625 * @}
Note:
See TracChangeset
for help on using the changeset viewer.