Ignore:
Timestamp:
2012-08-20T23:21:41Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0343a1b
Parents:
642dc72
Message:

Separate system IPC logic into dedicated ops structure hooks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/ops/datawrite.c

    r642dc72 re8039a86  
    3434
    3535#include <ipc/sysipc_ops.h>
     36#include <ipc/ipc.h>
     37#include <mm/slab.h>
     38#include <abi/errno.h>
     39#include <syscall/copy.h>
     40#include <config.h>
     41
     42static int request_preprocess(call_t *call, phone_t *phone)
     43{
     44        uintptr_t src = IPC_GET_ARG1(call->data);
     45        size_t size = IPC_GET_ARG2(call->data);
     46
     47        if (size > DATA_XFER_LIMIT) {
     48                int flags = IPC_GET_ARG3(call->data);
     49
     50                if (flags & IPC_XF_RESTRICT) {
     51                        size = DATA_XFER_LIMIT;
     52                        IPC_SET_ARG2(call->data, size);
     53                } else
     54                        return ELIMIT;
     55        }
     56
     57        call->buffer = (uint8_t *) malloc(size, 0);
     58        int rc = copy_from_uspace(call->buffer, (void *) src, size);
     59        if (rc != 0) {
     60                free(call->buffer);
     61                return rc;
     62        }
     63               
     64        return EOK;
     65}
     66
     67static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
     68{
     69        ASSERT(answer->buffer);
     70
     71        if (!IPC_GET_RETVAL(answer->data)) {
     72                /* The recipient agreed to receive data. */
     73                uintptr_t dst = (uintptr_t)IPC_GET_ARG1(answer->data);
     74                size_t size = (size_t)IPC_GET_ARG2(answer->data);
     75                size_t max_size = (size_t)IPC_GET_ARG2(*olddata);
     76                       
     77                if (size <= max_size) {
     78                        int rc = copy_to_uspace((void *) dst,
     79                            answer->buffer, size);
     80                        if (rc)
     81                                IPC_SET_RETVAL(answer->data, rc);
     82                } else {
     83                        IPC_SET_RETVAL(answer->data, ELIMIT);
     84                }
     85        }
     86        free(answer->buffer);
     87        answer->buffer = NULL;
     88
     89        return EOK;
     90}
     91
    3692
    3793sysipc_ops_t ipc_m_data_write_ops = {
    38         .request_preprocess = null_request_preprocess,
     94        .request_preprocess = request_preprocess,
    3995        .request_process = null_request_process,
    40         .answer_preprocess = null_answer_preprocess,
     96        .answer_preprocess = answer_preprocess,
    4197        .answer_process = null_answer_process,
    4298};
Note: See TracChangeset for help on using the changeset viewer.