Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/sysipc.c

    r6c34f587 r4e5dabf  
    612612                break;
    613613        }
     614       
     615        return 0;
     616}
     617
     618/** Make a fast call over IPC, wait for reply and return to user.
     619 *
     620 * This function can handle only three arguments of payload, but is faster than
     621 * the generic function (i.e. sys_ipc_call_sync_slow()).
     622 *
     623 * @param phoneid Phone handle for the call.
     624 * @param imethod Interface and method of the call.
     625 * @param arg1    Service-defined payload argument.
     626 * @param arg2    Service-defined payload argument.
     627 * @param arg3    Service-defined payload argument.
     628 * @param data    Address of user-space structure where the reply call will
     629 *                be stored.
     630 *
     631 * @return 0 on success.
     632 * @return ENOENT if there is no such phone handle.
     633 *
     634 */
     635sysarg_t sys_ipc_call_sync_fast(sysarg_t phoneid, sysarg_t imethod,
     636    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_data_t *data)
     637{
     638        phone_t *phone;
     639        if (phone_get(phoneid, &phone) != EOK)
     640                return ENOENT;
     641       
     642        call_t *call = ipc_call_alloc(0);
     643        IPC_SET_IMETHOD(call->data, imethod);
     644        IPC_SET_ARG1(call->data, arg1);
     645        IPC_SET_ARG2(call->data, arg2);
     646        IPC_SET_ARG3(call->data, arg3);
     647       
     648        /*
     649         * To achieve deterministic behavior, zero out arguments that are beyond
     650         * the limits of the fast version.
     651         */
     652        IPC_SET_ARG4(call->data, 0);
     653        IPC_SET_ARG5(call->data, 0);
     654       
     655        int res = request_preprocess(call, phone);
     656        int rc;
     657       
     658        if (!res) {
     659#ifdef CONFIG_UDEBUG
     660                udebug_stoppable_begin();
     661#endif
     662                rc = ipc_call_sync(phone, call);
     663#ifdef CONFIG_UDEBUG
     664                udebug_stoppable_end();
     665#endif
     666               
     667                if (rc != EOK) {
     668                        /* The call will be freed by ipc_cleanup(). */
     669                        return rc;
     670                }
     671               
     672                process_answer(call);
     673        } else
     674                IPC_SET_RETVAL(call->data, res);
     675       
     676        rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
     677        ipc_call_free(call);
     678        if (rc != 0)
     679                return rc;
     680       
     681        return 0;
     682}
     683
     684/** Make a synchronous IPC call allowing to transmit the entire payload.
     685 *
     686 * @param phoneid Phone handle for the call.
     687 * @param request User-space address of call data with the request.
     688 * @param reply   User-space address of call data where to store the
     689 *                answer.
     690 *
     691 * @return Zero on success or an error code.
     692 *
     693 */
     694sysarg_t sys_ipc_call_sync_slow(sysarg_t phoneid, ipc_data_t *request,
     695    ipc_data_t *reply)
     696{
     697        phone_t *phone;
     698        if (phone_get(phoneid, &phone) != EOK)
     699                return ENOENT;
     700       
     701        call_t *call = ipc_call_alloc(0);
     702        int rc = copy_from_uspace(&call->data.args, &request->args,
     703            sizeof(call->data.args));
     704        if (rc != 0) {
     705                ipc_call_free(call);
     706                return (sysarg_t) rc;
     707        }
     708       
     709        int res = request_preprocess(call, phone);
     710       
     711        if (!res) {
     712#ifdef CONFIG_UDEBUG
     713                udebug_stoppable_begin();
     714#endif
     715                rc = ipc_call_sync(phone, call);
     716#ifdef CONFIG_UDEBUG
     717                udebug_stoppable_end();
     718#endif
     719               
     720                if (rc != EOK) {
     721                        /* The call will be freed by ipc_cleanup(). */
     722                        return rc;
     723                }
     724               
     725                process_answer(call);
     726        } else
     727                IPC_SET_RETVAL(call->data, res);
     728       
     729        rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
     730        ipc_call_free(call);
     731        if (rc != 0)
     732                return rc;
    614733       
    615734        return 0;
Note: See TracChangeset for help on using the changeset viewer.