Rev 3606 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3606 | Rev 4377 | ||
---|---|---|---|
Line 330... | Line 330... | ||
330 | break; |
330 | break; |
331 | case IPC_M_DATA_WRITE: |
331 | case IPC_M_DATA_WRITE: |
332 | src = IPC_GET_ARG1(call->data); |
332 | src = IPC_GET_ARG1(call->data); |
333 | size = IPC_GET_ARG2(call->data); |
333 | size = IPC_GET_ARG2(call->data); |
334 | 334 | ||
335 | if ((size <= 0) || (size > DATA_XFER_LIMIT)) |
335 | if (size > DATA_XFER_LIMIT) |
336 | return ELIMIT; |
336 | return ELIMIT; |
337 | 337 | ||
338 | call->buffer = (uint8_t *) malloc(size, 0); |
338 | call->buffer = (uint8_t *) malloc(size, 0); |
339 | rc = copy_from_uspace(call->buffer, (void *) src, size); |
339 | rc = copy_from_uspace(call->buffer, (void *) src, size); |
340 | if (rc != 0) { |
340 | if (rc != 0) { |
Line 616... | Line 616... | ||
616 | ipc_backsend_err(phone, call, res); |
616 | ipc_backsend_err(phone, call, res); |
617 | 617 | ||
618 | return (unative_t) call; |
618 | return (unative_t) call; |
619 | } |
619 | } |
620 | 620 | ||
621 | /** Forward a received call to another destination. |
621 | /** Forward a received call to another destination - common code for both the |
- | 622 | * fast and the slow version. |
|
622 | * |
623 | * |
623 | * @param callid Hash of the call to forward. |
624 | * @param callid Hash of the call to forward. |
624 | * @param phoneid Phone handle to use for forwarding. |
625 | * @param phoneid Phone handle to use for forwarding. |
625 | * @param method New method to use for the forwarded call. |
626 | * @param method New method to use for the forwarded call. |
626 | * @param arg1 New value of the first argument for the forwarded call. |
627 | * @param arg1 New value of the first argument for the forwarded call. |
627 | * @param arg2 New value of the second argument for the forwarded call. |
628 | * @param arg2 New value of the second argument for the forwarded call. |
- | 629 | * @param arg3 New value of the third argument for the forwarded call. |
|
- | 630 | * @param arg4 New value of the fourth argument for the forwarded call. |
|
- | 631 | * @param arg5 New value of the fifth argument for the forwarded call. |
|
628 | * @param mode Flags that specify mode of the forward operation. |
632 | * @param mode Flags that specify mode of the forward operation. |
- | 633 | * @param slow If true, arg3, arg4 and arg5 are considered. Otherwise |
|
- | 634 | * the function considers only the fast version arguments: |
|
- | 635 | * i.e. arg1 and arg2. |
|
629 | * |
636 | * |
630 | * @return Return 0 on succes, otherwise return an error code. |
637 | * @return Return 0 on succes, otherwise return an error code. |
631 | * |
638 | * |
632 | * In case the original method is a system method, ARG1, ARG2 and ARG3 are |
- | |
633 | * overwritten in the forwarded message with the new method and the new arg1 and |
- | |
634 | * arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are rewritten with |
- | |
635 | * the new method, arg1 and arg2, respectively. Also note there is a set of |
- | |
636 | * immutable methods, for which the new method and argument is not set and |
- | |
637 | * these values are ignored. |
- | |
638 | * |
- | |
639 | * Warning: When implementing support for changing additional payload |
- | |
640 | * arguments, make sure that ARG5 is not rewritten for certain |
639 | * Warning: Make sure that ARG5 is not rewritten for certain system IPC |
641 | * system IPC |
- | |
642 | */ |
640 | */ |
643 | unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
641 | static unative_t sys_ipc_forward_common(unative_t callid, unative_t phoneid, |
644 | unative_t method, unative_t arg1, unative_t arg2, int mode) |
642 | unative_t method, unative_t arg1, unative_t arg2, unative_t arg3, |
- | 643 | unative_t arg4, unative_t arg5, int mode, bool slow) |
|
645 | { |
644 | { |
646 | call_t *call; |
645 | call_t *call; |
647 | phone_t *phone; |
646 | phone_t *phone; |
648 | 647 | ||
649 | call = get_call(callid); |
648 | call = get_call(callid); |
650 | if (!call) |
649 | if (!call) |
651 | return ENOENT; |
650 | return ENOENT; |
652 | 651 | ||
653 | call->flags |= IPC_CALL_FORWARDED; |
652 | call->flags |= IPC_CALL_FORWARDED; |
654 | 653 | ||
655 | GET_CHECK_PHONE(phone, phoneid, { |
654 | GET_CHECK_PHONE(phone, phoneid, { |
656 | IPC_SET_RETVAL(call->data, EFORWARD); |
655 | IPC_SET_RETVAL(call->data, EFORWARD); |
657 | ipc_answer(&TASK->answerbox, call); |
656 | ipc_answer(&TASK->answerbox, call); |
Line 664... | Line 663... | ||
664 | return EPERM; |
663 | return EPERM; |
665 | } |
664 | } |
666 | 665 | ||
667 | /* |
666 | /* |
668 | * Userspace is not allowed to change method of system methods on |
667 | * Userspace is not allowed to change method of system methods on |
669 | * forward, allow changing ARG1, ARG2 and ARG3 by means of method, |
668 | * forward, allow changing ARG1, ARG2, ARG3 and ARG4 by means of method, |
670 | * arg1 and arg2. |
669 | * arg1, arg2 and arg3. |
671 | * If the method is immutable, don't change anything. |
670 | * If the method is immutable, don't change anything. |
672 | */ |
671 | */ |
673 | if (!method_is_immutable(IPC_GET_METHOD(call->data))) { |
672 | if (!method_is_immutable(IPC_GET_METHOD(call->data))) { |
674 | if (method_is_system(IPC_GET_METHOD(call->data))) { |
673 | if (method_is_system(IPC_GET_METHOD(call->data))) { |
675 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) |
674 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) |
676 | phone_dealloc(IPC_GET_ARG5(call->data)); |
675 | phone_dealloc(IPC_GET_ARG5(call->data)); |
677 | 676 | ||
678 | IPC_SET_ARG1(call->data, method); |
677 | IPC_SET_ARG1(call->data, method); |
679 | IPC_SET_ARG2(call->data, arg1); |
678 | IPC_SET_ARG2(call->data, arg1); |
680 | IPC_SET_ARG3(call->data, arg2); |
679 | IPC_SET_ARG3(call->data, arg2); |
- | 680 | if (slow) { |
|
- | 681 | IPC_SET_ARG4(call->data, arg3); |
|
- | 682 | /* |
|
- | 683 | * For system methods we deliberately don't |
|
- | 684 | * overwrite ARG5. |
|
- | 685 | */ |
|
- | 686 | } |
|
681 | } else { |
687 | } else { |
682 | IPC_SET_METHOD(call->data, method); |
688 | IPC_SET_METHOD(call->data, method); |
683 | IPC_SET_ARG1(call->data, arg1); |
689 | IPC_SET_ARG1(call->data, arg1); |
684 | IPC_SET_ARG2(call->data, arg2); |
690 | IPC_SET_ARG2(call->data, arg2); |
- | 691 | if (slow) { |
|
- | 692 | IPC_SET_ARG3(call->data, arg3); |
|
- | 693 | IPC_SET_ARG4(call->data, arg4); |
|
- | 694 | IPC_SET_ARG5(call->data, arg5); |
|
- | 695 | } |
|
685 | } |
696 | } |
686 | } |
697 | } |
687 | 698 | ||
688 | return ipc_forward(call, phone, &TASK->answerbox, mode); |
699 | return ipc_forward(call, phone, &TASK->answerbox, mode); |
689 | } |
700 | } |
690 | 701 | ||
- | 702 | /** Forward a received call to another destination - fast version. |
|
- | 703 | * |
|
- | 704 | * @param callid Hash of the call to forward. |
|
- | 705 | * @param phoneid Phone handle to use for forwarding. |
|
- | 706 | * @param method New method to use for the forwarded call. |
|
- | 707 | * @param arg1 New value of the first argument for the forwarded call. |
|
- | 708 | * @param arg2 New value of the second argument for the forwarded call. |
|
- | 709 | * @param mode Flags that specify mode of the forward operation. |
|
- | 710 | * |
|
- | 711 | * @return Return 0 on succes, otherwise return an error code. |
|
- | 712 | * |
|
- | 713 | * In case the original method is a system method, ARG1, ARG2 and ARG3 are |
|
- | 714 | * overwritten in the forwarded message with the new method and the new |
|
- | 715 | * arg1 and arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are |
|
- | 716 | * rewritten with the new method, arg1 and arg2, respectively. Also note there |
|
- | 717 | * is a set of immutable methods, for which the new method and arguments are not |
|
- | 718 | * set and these values are ignored. |
|
- | 719 | */ |
|
- | 720 | unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
|
- | 721 | unative_t method, unative_t arg1, unative_t arg2, int mode) |
|
- | 722 | { |
|
- | 723 | return sys_ipc_forward_common(callid, phoneid, method, arg1, arg2, 0, 0, |
|
- | 724 | 0, mode, false); |
|
- | 725 | } |
|
- | 726 | ||
- | 727 | /** Forward a received call to another destination - slow version. |
|
- | 728 | * |
|
- | 729 | * @param callid Hash of the call to forward. |
|
- | 730 | * @param phoneid Phone handle to use for forwarding. |
|
- | 731 | * @param data Userspace address of the new IPC data. |
|
- | 732 | * @param mode Flags that specify mode of the forward operation. |
|
- | 733 | * |
|
- | 734 | * @return Return 0 on succes, otherwise return an error code. |
|
- | 735 | * |
|
- | 736 | * This function is the slow verision of the sys_ipc_forward_fast interface. |
|
- | 737 | * It can copy all five new arguments and the new method from the userspace. |
|
- | 738 | * It naturally extends the functionality of the fast version. For system |
|
- | 739 | * methods, it additionally stores the new value of arg3 to ARG4. For non-system |
|
- | 740 | * methods, it additionally stores the new value of arg3, arg4 and arg5, |
|
- | 741 | * respectively, to ARG3, ARG4 and ARG5, respectively. |
|
- | 742 | */ |
|
- | 743 | unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid, |
|
- | 744 | ipc_data_t *data, int mode) |
|
- | 745 | { |
|
- | 746 | ipc_data_t newdata; |
|
- | 747 | int rc; |
|
- | 748 | ||
- | 749 | rc = copy_from_uspace(&newdata.args, &data->args, |
|
- | 750 | sizeof(newdata.args)); |
|
- | 751 | if (rc != 0) |
|
- | 752 | return (unative_t) rc; |
|
- | 753 | ||
- | 754 | return sys_ipc_forward_common(callid, phoneid, |
|
- | 755 | IPC_GET_METHOD(newdata), IPC_GET_ARG1(newdata), |
|
- | 756 | IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata), |
|
- | 757 | IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true); |
|
- | 758 | } |
|
- | 759 | ||
691 | /** Answer an IPC call - fast version. |
760 | /** Answer an IPC call - fast version. |
692 | * |
761 | * |
693 | * This function can handle only two return arguments of payload, but is faster |
762 | * This function can handle only two return arguments of payload, but is faster |
694 | * than the generic sys_ipc_answer(). |
763 | * than the generic sys_ipc_answer(). |
695 | * |
764 | * |
Line 865... | Line 934... | ||
865 | goto restart; |
934 | goto restart; |
866 | 935 | ||
867 | /* Include phone address('id') of the caller in the request, |
936 | /* Include phone address('id') of the caller in the request, |
868 | * copy whole call->data, not only call->data.args */ |
937 | * copy whole call->data, not only call->data.args */ |
869 | if (STRUCT_TO_USPACE(calldata, &call->data)) { |
938 | if (STRUCT_TO_USPACE(calldata, &call->data)) { |
- | 939 | /* |
|
- | 940 | * The callee will not receive this call and no one else has |
|
- | 941 | * a chance to answer it. Reply with the EPARTY error code. |
|
- | 942 | */ |
|
- | 943 | ipc_data_t saved_data; |
|
- | 944 | int saveddata = 0; |
|
- | 945 | ||
- | 946 | if (answer_need_old(call)) { |
|
- | 947 | memcpy(&saved_data, &call->data, sizeof(call->data)); |
|
- | 948 | saveddata = 1; |
|
- | 949 | } |
|
- | 950 | ||
- | 951 | IPC_SET_RETVAL(call->data, EPARTY); |
|
- | 952 | (void) answer_preprocess(call, saveddata ? &saved_data : NULL); |
|
- | 953 | ipc_answer(&TASK->answerbox, call); |
|
870 | return 0; |
954 | return 0; |
871 | } |
955 | } |
872 | return (unative_t)call; |
956 | return (unative_t)call; |
873 | } |
957 | } |
874 | 958 |