Ignore:
Timestamp:
2012-08-20T23:21:41Z (12 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/dataread.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        size_t size = IPC_GET_ARG2(call->data);
     45
     46        if (size > DATA_XFER_LIMIT) {
     47                int flags = IPC_GET_ARG3(call->data);
     48
     49                if (flags & IPC_XF_RESTRICT)
     50                        IPC_SET_ARG2(call->data, DATA_XFER_LIMIT);
     51                else
     52                        return ELIMIT;
     53        }
     54
     55        return EOK;
     56}
     57
     58static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
     59{
     60        ASSERT(!answer->buffer);
     61
     62        if (!IPC_GET_RETVAL(answer->data)) {
     63                /* The recipient agreed to send data. */
     64                uintptr_t src = IPC_GET_ARG1(answer->data);
     65                uintptr_t dst = IPC_GET_ARG1(*olddata);
     66                size_t max_size = IPC_GET_ARG2(*olddata);
     67                size_t size = IPC_GET_ARG2(answer->data);
     68                if (size && size <= max_size) {
     69                        /*
     70                         * Copy the destination VA so that this piece of
     71                         * information is not lost.
     72                         */
     73                        IPC_SET_ARG1(answer->data, dst);
     74                               
     75                        answer->buffer = malloc(size, 0);
     76                        int rc = copy_from_uspace(answer->buffer,
     77                            (void *) src, size);
     78                        if (rc) {
     79                                IPC_SET_RETVAL(answer->data, rc);
     80                                free(answer->buffer);
     81                                answer->buffer = NULL;
     82                        }
     83                } else if (!size) {
     84                        IPC_SET_RETVAL(answer->data, EOK);
     85                } else {
     86                        IPC_SET_RETVAL(answer->data, ELIMIT);
     87                }
     88        }
     89
     90        return EOK;
     91}
    3692
    3793sysipc_ops_t ipc_m_data_read_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.