Changeset 01c3bb4 in mainline for kernel/generic/src/ipc/sysipc.c
- Timestamp:
- 2017-11-25T15:43:25Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ce4a21a0
- Parents:
- 98cb5e0d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/sysipc.c
r98cb5e0d r01c3bb4 53 53 #include <print.h> 54 54 #include <macros.h> 55 #include <cap/cap.h> 55 56 56 57 #define STRUCT_TO_USPACE(dst, src) copy_to_uspace((dst), (src), sizeof(*(src))) … … 447 448 * Common code for both the fast and the slow version. 448 449 * 449 * @param c allid Hash of the call to forward.450 * @param handle Phone capabilityto use for forwarding.450 * @param chandle Call handle of the forwarded call. 451 * @param phandle Phone handle to use for forwarding. 451 452 * @param imethod New interface and method to use for the forwarded call. 452 453 * @param arg1 New value of the first argument for the forwarded call. … … 465 466 * 466 467 */ 467 static sysarg_t sys_ipc_forward_common(sysarg_t c allid, sysarg_thandle,468 static sysarg_t sys_ipc_forward_common(sysarg_t chandle, sysarg_t phandle, 468 469 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 469 470 sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow) 470 471 { 471 call_t *call = get_call(callid);472 if (!c all)472 kobject_t *ckobj = cap_unpublish(TASK, chandle, KOBJECT_TYPE_CALL); 473 if (!ckobj) 473 474 return ENOENT; 474 475 476 call_t *call = ckobj->call; 477 475 478 ipc_data_t old; 476 479 bool need_old = answer_need_old(call); … … 481 484 int rc; 482 485 483 kobject_t * kobj = kobject_get(TASK,handle, KOBJECT_TYPE_PHONE);484 if (! kobj) {486 kobject_t *pkobj = kobject_get(TASK, phandle, KOBJECT_TYPE_PHONE); 487 if (!pkobj) { 485 488 rc = ENOENT; 486 489 goto error; … … 528 531 } 529 532 530 rc = ipc_forward(call, kobj->phone, &TASK->answerbox, mode);533 rc = ipc_forward(call, pkobj->phone, &TASK->answerbox, mode); 531 534 if (rc != EOK) { 532 535 after_forward = true; … … 534 537 } 535 538 536 kobject_put(kobj); 539 cap_free(TASK, chandle); 540 kobject_put(ckobj); 541 kobject_put(pkobj); 537 542 return EOK; 538 543 … … 545 550 ipc_answer(&TASK->answerbox, call); 546 551 547 if (kobj) 548 kobject_put(kobj); 552 /* Republish the capability so that the call does not get lost. */ 553 cap_publish(TASK, chandle, ckobj); 554 555 if (pkobj) 556 kobject_put(pkobj); 549 557 return rc; 550 558 } … … 559 567 * arguments are not set and these values are ignored. 560 568 * 561 * @param c allid Hashof the call to forward.562 * @param handlePhone handle to use for forwarding.569 * @param chandle Call handle of the call to forward. 570 * @param phandle Phone handle to use for forwarding. 563 571 * @param imethod New interface and method to use for the forwarded call. 564 572 * @param arg1 New value of the first argument for the forwarded call. … … 569 577 * 570 578 */ 571 sysarg_t sys_ipc_forward_fast(sysarg_t c allid, sysarg_thandle,579 sysarg_t sys_ipc_forward_fast(sysarg_t chandle, sysarg_t phandle, 572 580 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode) 573 581 { 574 return sys_ipc_forward_common(c allid, handle, imethod, arg1, arg2, 0, 0,575 0, mode, false);582 return sys_ipc_forward_common(chandle, phandle, imethod, arg1, arg2, 0, 583 0, 0, mode, false); 576 584 } 577 585 … … 585 593 * and arg5, respectively, to ARG3, ARG4 and ARG5, respectively. 586 594 * 587 * @param c allid Hashof the call to forward.588 * @param handle Phone handle to use for forwarding.589 * @param data Userspace address of the new IPC data.590 * @param mode Flags that specify mode of the forward operation.595 * @param chandle Call handle of the call to forward. 596 * @param phandle Phone handle to use for forwarding. 597 * @param data Userspace address of the new IPC data. 598 * @param mode Flags that specify mode of the forward operation. 591 599 * 592 600 * @return 0 on succes, otherwise an error code. 593 601 * 594 602 */ 595 sysarg_t sys_ipc_forward_slow(sysarg_t c allid, sysarg_thandle,603 sysarg_t sys_ipc_forward_slow(sysarg_t chandle, sysarg_t phandle, 596 604 ipc_data_t *data, unsigned int mode) 597 605 { … … 602 610 return (sysarg_t) rc; 603 611 604 return sys_ipc_forward_common(c allid,handle,612 return sys_ipc_forward_common(chandle, phandle, 605 613 IPC_GET_IMETHOD(newdata), IPC_GET_ARG1(newdata), 606 614 IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata), 607 IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true); 615 IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true); 608 616 } 609 617 … … 613 621 * than the generic sys_ipc_answer(). 614 622 * 615 * @param c allid Hash of the callto be answered.616 * @param retval Return value of the answer.617 * @param arg1 Service-defined return value.618 * @param arg2 Service-defined return value.619 * @param arg3 Service-defined return value.620 * @param arg4 Service-defined return value.623 * @param chandle Call handle to be answered. 624 * @param retval Return value of the answer. 625 * @param arg1 Service-defined return value. 626 * @param arg2 Service-defined return value. 627 * @param arg3 Service-defined return value. 628 * @param arg4 Service-defined return value. 621 629 * 622 630 * @return 0 on success, otherwise an error code. 623 631 * 624 632 */ 625 sysarg_t sys_ipc_answer_fast(sysarg_t callid, sysarg_t retval, 626 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) 627 { 628 /* Do not answer notification callids */ 629 if (callid & IPC_CALLID_NOTIFICATION) 630 return 0; 631 632 call_t *call = get_call(callid); 633 if (!call) 633 sysarg_t sys_ipc_answer_fast(sysarg_t chandle, sysarg_t retval, sysarg_t arg1, 634 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) 635 { 636 kobject_t *kobj = cap_unpublish(TASK, chandle, KOBJECT_TYPE_CALL); 637 if (!kobj) 634 638 return ENOENT; 635 639 640 call_t *call = kobj->call; 641 636 642 ipc_data_t saved_data; 637 643 bool saved; … … 657 663 658 664 ipc_answer(&TASK->answerbox, call); 665 666 kobject_put(kobj); 667 cap_free(TASK, chandle); 668 659 669 return rc; 660 670 } … … 662 672 /** Answer an IPC call. 663 673 * 664 * @param c allid Hash of the callto be answered.665 * @param data Userspace address of call data with the answer.674 * @param chandle Call handle to be answered. 675 * @param data Userspace address of call data with the answer. 666 676 * 667 677 * @return 0 on success, otherwise an error code. 668 678 * 669 679 */ 670 sysarg_t sys_ipc_answer_slow(sysarg_t callid, ipc_data_t *data) 671 { 672 /* Do not answer notification callids */ 673 if (callid & IPC_CALLID_NOTIFICATION) 674 return 0; 675 676 call_t *call = get_call(callid); 677 if (!call) 680 sysarg_t sys_ipc_answer_slow(sysarg_t chandle, ipc_data_t *data) 681 { 682 kobject_t *kobj = cap_unpublish(TASK, chandle, KOBJECT_TYPE_CALL); 683 if (!kobj) 678 684 return ENOENT; 679 685 686 call_t *call = kobj->call; 687 680 688 ipc_data_t saved_data; 681 689 bool saved; … … 689 697 int rc = copy_from_uspace(&call->data.args, &data->args, 690 698 sizeof(call->data.args)); 691 if (rc != 0) 699 if (rc != 0) { 700 /* 701 * Republish the capability so that the call does not get lost. 702 */ 703 cap_publish(TASK, chandle, kobj); 692 704 return rc; 705 } 693 706 694 707 rc = answer_preprocess(call, saved ? &saved_data : NULL); 695 708 696 709 ipc_answer(&TASK->answerbox, call); 710 711 kobject_put(kobj); 712 cap_free(TASK, chandle); 713 697 714 return rc; 698 715 } … … 727 744 * for explanation. 728 745 * 729 * @return Hash of the call. 746 * @return Capability handle of the received request. 747 * @return CAP_NIL for answers, notifications and when there is no call. 748 * @return Negative error code on error. 730 749 */ 731 750 sysarg_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, … … 746 765 udebug_stoppable_end(); 747 766 #endif 748 749 if (!call) 750 return 0; 767 768 if (!call) { 769 STRUCT_TO_USPACE(calldata, &(ipc_data_t){}); 770 return CAP_NIL; 771 } 751 772 752 773 if (call->flags & IPC_CALL_NOTIF) { … … 759 780 kobject_put(call->kobject); 760 781 761 return (sysarg_t) call;782 return CAP_NIL; 762 783 } 763 784 … … 775 796 kobject_put(call->kobject); 776 797 777 return (sysarg_t) call;798 return CAP_NIL; 778 799 } 779 800 … … 781 802 goto restart; 782 803 783 /* Include phone address('id') of the caller in the request, 784 * copy whole call->data, not only call->data.args */ 785 if (STRUCT_TO_USPACE(calldata, &call->data)) { 786 /* 787 * The callee will not receive this call and no one else has 788 * a chance to answer it. Reply with the EPARTY error code. 789 */ 790 ipc_data_t saved_data; 791 bool saved; 792 793 if (answer_need_old(call)) { 794 memcpy(&saved_data, &call->data, sizeof(call->data)); 795 saved = true; 796 } else 797 saved = false; 798 799 IPC_SET_RETVAL(call->data, EPARTY); 800 (void) answer_preprocess(call, saved ? &saved_data : NULL); 801 ipc_answer(&TASK->answerbox, call); 802 return 0; 803 } 804 805 return (sysarg_t) call; 804 int rc; 805 cap_handle_t handle = cap_alloc(TASK); 806 if (handle < 0) { 807 rc = handle; 808 goto error; 809 } 810 811 /* 812 * Include phone hash of the caller in the request, copy the whole 813 * call->data, not only call->data.args. 814 */ 815 rc = STRUCT_TO_USPACE(calldata, &call->data); 816 if (rc != EOK) 817 goto error; 818 819 kobject_add_ref(call->kobject); 820 cap_publish(TASK, handle, call->kobject); 821 return handle; 822 823 error: 824 if (handle >= 0) 825 cap_free(TASK, handle); 826 827 /* 828 * The callee will not receive this call and no one else has a chance to 829 * answer it. Reply with the EPARTY error code. 830 */ 831 ipc_data_t saved_data; 832 bool saved; 833 834 if (answer_need_old(call)) { 835 memcpy(&saved_data, &call->data, sizeof(call->data)); 836 saved = true; 837 } else 838 saved = false; 839 840 IPC_SET_RETVAL(call->data, EPARTY); 841 (void) answer_preprocess(call, saved ? &saved_data : NULL); 842 ipc_answer(&TASK->answerbox, call); 843 844 return rc; 806 845 } 807 846
Note:
See TracChangeset
for help on using the changeset viewer.