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 | ||