Changeset 48daf64 in mainline
- Timestamp:
- 2009-01-25T20:10:10Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a68ba8b
- Parents:
- 161ae09
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/sysipc.h
r161ae09 r48daf64 54 54 unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, 55 55 unative_t method, unative_t arg1, unative_t arg2, int mode); 56 unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid, 57 ipc_data_t *data, int mode); 56 58 unative_t sys_ipc_hangup(int phoneid); 57 59 unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method, -
kernel/generic/include/syscall/syscall.h
r161ae09 r48daf64 63 63 SYS_IPC_ANSWER_SLOW, 64 64 SYS_IPC_FORWARD_FAST, 65 SYS_IPC_FORWARD_SLOW, 65 66 SYS_IPC_WAIT, 66 67 SYS_IPC_HANGUP, -
kernel/generic/src/ipc/sysipc.c
r161ae09 r48daf64 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. 623 * 624 * @param callid Hash of the call to forward. 625 * @param phoneid Phone handle to use for forwarding. 626 * @param method New method to use for the forwarded call. 627 * @param arg1 New value of the first 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. 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. 636 * 637 * @return Return 0 on succes, otherwise return an error code. 638 * 639 * Warning: Make sure that ARG5 is not rewritten for certain system IPC 640 */ 641 static unative_t sys_ipc_forward_common(unative_t callid, unative_t phoneid, 642 unative_t method, unative_t arg1, unative_t arg2, unative_t arg3, 643 unative_t arg4, unative_t arg5, int mode, bool slow) 644 { 645 call_t *call; 646 phone_t *phone; 647 648 call = get_call(callid); 649 if (!call) 650 return ENOENT; 651 652 call->flags |= IPC_CALL_FORWARDED; 653 654 GET_CHECK_PHONE(phone, phoneid, { 655 IPC_SET_RETVAL(call->data, EFORWARD); 656 ipc_answer(&TASK->answerbox, call); 657 return ENOENT; 658 }); 659 660 if (!method_is_forwardable(IPC_GET_METHOD(call->data))) { 661 IPC_SET_RETVAL(call->data, EFORWARD); 662 ipc_answer(&TASK->answerbox, call); 663 return EPERM; 664 } 665 666 /* 667 * Userspace is not allowed to change method of system methods on 668 * forward, allow changing ARG1, ARG2, ARG3 and ARG4 by means of method, 669 * arg1, arg2 and arg3. 670 * If the method is immutable, don't change anything. 671 */ 672 if (!method_is_immutable(IPC_GET_METHOD(call->data))) { 673 if (method_is_system(IPC_GET_METHOD(call->data))) { 674 if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) 675 phone_dealloc(IPC_GET_ARG5(call->data)); 676 677 IPC_SET_ARG1(call->data, method); 678 IPC_SET_ARG2(call->data, arg1); 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 } 687 } else { 688 IPC_SET_METHOD(call->data, method); 689 IPC_SET_ARG1(call->data, arg1); 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 } 696 } 697 } 698 699 return ipc_forward(call, phone, &TASK->answerbox, mode); 700 } 701 702 /** Forward a received call to another destination - fast version. 622 703 * 623 704 * @param callid Hash of the call to forward. … … 631 712 * 632 713 * 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 641 * system IPC 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. 642 719 */ 643 720 unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, 644 721 unative_t method, unative_t arg1, unative_t arg2, int mode) 645 722 { 646 call_t *call; 647 phone_t *phone; 648 649 call = get_call(callid); 650 if (!call) 651 return ENOENT; 652 653 call->flags |= IPC_CALL_FORWARDED; 654 655 GET_CHECK_PHONE(phone, phoneid, { 656 IPC_SET_RETVAL(call->data, EFORWARD); 657 ipc_answer(&TASK->answerbox, call); 658 return ENOENT; 659 }); 660 661 if (!method_is_forwardable(IPC_GET_METHOD(call->data))) { 662 IPC_SET_RETVAL(call->data, EFORWARD); 663 ipc_answer(&TASK->answerbox, call); 664 return EPERM; 665 } 666 667 /* 668 * Userspace is not allowed to change method of system methods on 669 * forward, allow changing ARG1, ARG2 and ARG3 by means of method, 670 * arg1 and arg2. 671 * If the method is immutable, don't change anything. 672 */ 673 if (!method_is_immutable(IPC_GET_METHOD(call->data))) { 674 if (method_is_system(IPC_GET_METHOD(call->data))) { 675 if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) 676 phone_dealloc(IPC_GET_ARG5(call->data)); 677 678 IPC_SET_ARG1(call->data, method); 679 IPC_SET_ARG2(call->data, arg1); 680 IPC_SET_ARG3(call->data, arg2); 681 } else { 682 IPC_SET_METHOD(call->data, method); 683 IPC_SET_ARG1(call->data, arg1); 684 IPC_SET_ARG2(call->data, arg2); 685 } 686 } 687 688 return ipc_forward(call, phone, &TASK->answerbox, mode); 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); 689 758 } 690 759 -
kernel/generic/src/syscall/syscall.c
r161ae09 r48daf64 165 165 (syshandler_t) sys_ipc_answer_slow, 166 166 (syshandler_t) sys_ipc_forward_fast, 167 (syshandler_t) sys_ipc_forward_slow, 167 168 (syshandler_t) sys_ipc_wait_for_call, 168 169 (syshandler_t) sys_ipc_hangup, -
uspace/app/trace/syscalls.c
r161ae09 r48daf64 60 60 [SYS_IPC_ANSWER_SLOW] = { "ipc_answer_slow", 2, V_ERRNO }, 61 61 [SYS_IPC_FORWARD_FAST] = { "ipc_forward_fast", 6, V_ERRNO }, 62 [SYS_IPC_FORWARD_SLOW] = { "ipc_forward_slow", 3, V_ERRNO }, 62 63 [SYS_IPC_WAIT] = { "ipc_wait_for_call", 3, V_HASH }, 63 64 [SYS_IPC_HANGUP] = { "ipc_hangup", 1, V_ERRNO }, -
uspace/lib/libc/generic/ipc.c
r161ae09 r48daf64 667 667 } 668 668 669 670 int ipc_forward_slow(ipc_callid_t callid, int phoneid, int method, 671 ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, 672 int mode) 673 { 674 ipc_call_t data; 675 676 IPC_SET_METHOD(data, method); 677 IPC_SET_ARG1(data, arg1); 678 IPC_SET_ARG2(data, arg2); 679 IPC_SET_ARG3(data, arg3); 680 IPC_SET_ARG4(data, arg4); 681 IPC_SET_ARG5(data, arg5); 682 683 return __SYSCALL3(SYS_IPC_FORWARD_SLOW, callid, (sysarg_t) &data, mode); 684 } 685 669 686 /** Wrapper for making IPC_M_SHARE_IN calls. 670 687 * -
uspace/lib/libc/include/ipc/ipc.h
r161ae09 r48daf64 253 253 extern int ipc_unregister_irq(int, int); 254 254 extern int ipc_forward_fast(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, int); 255 extern int ipc_forward_slow(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, 256 ipcarg_t, ipcarg_t, ipcarg_t, int); 255 257 256 258
Note:
See TracChangeset
for help on using the changeset viewer.