Changeset 48daf64 in mainline


Ignore:
Timestamp:
2009-01-25T20:10:10Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a68ba8b
Parents:
161ae09
Message:

Introduce a new syscall: SYS_IPC_FORWARD_SLOW.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/sysipc.h

    r161ae09 r48daf64  
    5454unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
    5555    unative_t method, unative_t arg1, unative_t arg2, int mode);
     56unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
     57    ipc_data_t *data, int mode);
    5658unative_t sys_ipc_hangup(int phoneid);
    5759unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
  • kernel/generic/include/syscall/syscall.h

    r161ae09 r48daf64  
    6363        SYS_IPC_ANSWER_SLOW,
    6464        SYS_IPC_FORWARD_FAST,
     65        SYS_IPC_FORWARD_SLOW,
    6566        SYS_IPC_WAIT,
    6667        SYS_IPC_HANGUP,
  • kernel/generic/src/ipc/sysipc.c

    r161ae09 r48daf64  
    619619}
    620620
    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 */
     641static 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.
    622703 *
    623704 * @param callid        Hash of the call to forward.
     
    631712 *
    632713 * 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.
    642719 */
    643720unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
    644721    unative_t method, unative_t arg1, unative_t arg2, int mode)
    645722{
    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 */
     743unative_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);
    689758}
    690759
  • kernel/generic/src/syscall/syscall.c

    r161ae09 r48daf64  
    165165        (syshandler_t) sys_ipc_answer_slow,
    166166        (syshandler_t) sys_ipc_forward_fast,
     167        (syshandler_t) sys_ipc_forward_slow,
    167168        (syshandler_t) sys_ipc_wait_for_call,
    168169        (syshandler_t) sys_ipc_hangup,
  • uspace/app/trace/syscalls.c

    r161ae09 r48daf64  
    6060    [SYS_IPC_ANSWER_SLOW] = { "ipc_answer_slow",        2,      V_ERRNO },
    6161    [SYS_IPC_FORWARD_FAST] = { "ipc_forward_fast",      6,      V_ERRNO },
     62    [SYS_IPC_FORWARD_SLOW] = { "ipc_forward_slow",      3,      V_ERRNO },
    6263    [SYS_IPC_WAIT] = { "ipc_wait_for_call",             3,      V_HASH },
    6364    [SYS_IPC_HANGUP] = { "ipc_hangup",                  1,      V_ERRNO },
  • uspace/lib/libc/generic/ipc.c

    r161ae09 r48daf64  
    667667}
    668668
     669
     670int 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
    669686/** Wrapper for making IPC_M_SHARE_IN calls.
    670687 *
  • uspace/lib/libc/include/ipc/ipc.h

    r161ae09 r48daf64  
    253253extern int ipc_unregister_irq(int, int);
    254254extern int ipc_forward_fast(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, int);
     255extern int ipc_forward_slow(ipc_callid_t, int, int, ipcarg_t, ipcarg_t,
     256    ipcarg_t, ipcarg_t, ipcarg_t, int);
    255257
    256258
Note: See TracChangeset for help on using the changeset viewer.