Ignore:
File:
1 edited

Legend:

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

    rf6bffee rab34cc9  
    4040#include <debug.h>
    4141#include <ipc/ipc.h>
     42#include <abi/ipc/methods.h>
    4243#include <ipc/sysipc.h>
    4344#include <ipc/irq.h>
    4445#include <ipc/ipcrsc.h>
     46#include <ipc/event.h>
    4547#include <ipc/kbox.h>
    4648#include <synch/waitq.h>
     
    5254#include <mm/as.h>
    5355#include <print.h>
     56#include <macros.h>
    5457
    5558/**
     
    133136        case IPC_M_DATA_WRITE:
    134137        case IPC_M_DATA_READ:
     138        case IPC_M_STATE_CHANGE_AUTHORIZE:
    135139                return true;
    136140        default:
     
    163167        case IPC_M_DATA_WRITE:
    164168        case IPC_M_DATA_READ:
     169        case IPC_M_STATE_CHANGE_AUTHORIZE:
    165170                return true;
    166171        default:
     
    248253                        /* The connection was accepted */
    249254                        phone_connect(phoneid, &answer->sender->answerbox);
    250                         /* Set 'task hash' as arg4 of response */
    251                         IPC_SET_ARG4(answer->data, (sysarg_t) TASK);
    252255                        /* Set 'phone hash' as arg5 of response */
    253256                        IPC_SET_ARG5(answer->data,
     
    333336                free(answer->buffer);
    334337                answer->buffer = NULL;
     338        } else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) {
     339                if (!IPC_GET_RETVAL(answer->data)) {
     340                        /* The recipient authorized the change of state. */
     341                        phone_t *recipient_phone;
     342                        task_t *other_task_s;
     343                        task_t *other_task_r;
     344                        int rc;
     345
     346                        rc = phone_get(IPC_GET_ARG1(answer->data),
     347                            &recipient_phone);
     348                        if (rc != EOK) {
     349                                IPC_SET_RETVAL(answer->data, ENOENT);
     350                                return ENOENT;
     351                        }
     352
     353                        mutex_lock(&recipient_phone->lock);
     354                        if (recipient_phone->state != IPC_PHONE_CONNECTED) {
     355                                mutex_unlock(&recipient_phone->lock);
     356                                IPC_SET_RETVAL(answer->data, EINVAL);
     357                                return EINVAL;
     358                        }
     359
     360                        other_task_r = recipient_phone->callee->task;
     361                        other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
     362
     363                        /*
     364                         * See if both the sender and the recipient meant the
     365                         * same third party task.
     366                         */
     367                        if (other_task_r != other_task_s) {
     368                                IPC_SET_RETVAL(answer->data, EINVAL);
     369                                rc = EINVAL;
     370                        } else {
     371                                rc = event_task_notify_5(other_task_r,
     372                                    EVENT_TASK_STATE_CHANGE, false,
     373                                    IPC_GET_ARG1(*olddata),
     374                                    IPC_GET_ARG2(*olddata),
     375                                    IPC_GET_ARG3(*olddata),
     376                                    LOWER32(olddata->task_id),
     377                                    UPPER32(olddata->task_id));
     378                                IPC_SET_RETVAL(answer->data, rc);
     379                        }
     380
     381                        mutex_unlock(&recipient_phone->lock);
     382                        return rc;
     383                }
    335384        }
    336385       
     
    426475        case IPC_M_DATA_READ: {
    427476                size_t size = IPC_GET_ARG2(call->data);
    428                 if (size <= 0)
    429                         return ELIMIT;
    430477                if (size > DATA_XFER_LIMIT) {
    431478                        int flags = IPC_GET_ARG3(call->data);
     
    459506                break;
    460507        }
     508        case IPC_M_STATE_CHANGE_AUTHORIZE: {
     509                phone_t *sender_phone;
     510                task_t *other_task_s;
     511
     512                if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
     513                        return ENOENT;
     514
     515                mutex_lock(&sender_phone->lock);
     516                if (sender_phone->state != IPC_PHONE_CONNECTED) {
     517                        mutex_unlock(&sender_phone->lock);
     518                        return EINVAL;
     519                }
     520
     521                other_task_s = sender_phone->callee->task;
     522
     523                mutex_unlock(&sender_phone->lock);
     524
     525                /* Remember the third party task hash. */
     526                IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
     527                break;
     528        }
    461529#ifdef CONFIG_UDEBUG
    462         case IPC_M_DEBUG_ALL:
     530        case IPC_M_DEBUG:
    463531                return udebug_request_preprocess(call, phone);
    464532#endif
     
    495563                /*
    496564                 * This must be an affirmative answer to IPC_M_DATA_READ
    497                  * or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ...
     565                 * or IPC_M_DEBUG/UDEBUG_M_MEM_READ...
    498566                 *
    499567                 */
     
    531599       
    532600        switch (IPC_GET_IMETHOD(call->data)) {
    533         case IPC_M_DEBUG_ALL:
     601        case IPC_M_DEBUG:
    534602                return -1;
    535603        default:
Note: See TracChangeset for help on using the changeset viewer.