Subversion Repositories HelenOS

Rev

Rev 2098 | Rev 2471 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2098 Rev 2359
Line 69... Line 69...
69
 * - some system messages may be forwarded, for some of them
69
 * - some system messages may be forwarded, for some of them
70
 *   it is useless
70
 *   it is useless
71
 */
71
 */
72
static inline int is_forwardable(unative_t method)
72
static inline int is_forwardable(unative_t method)
73
{
73
{
74
    if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND \
74
    if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND ||
75
        || method == IPC_M_AS_AREA_RECV)
75
        method == IPC_M_AS_AREA_RECV)
76
        return 0; /* This message is meant only for the receiver */
76
        return 0; /* This message is meant only for the receiver */
77
    return 1;
77
    return 1;
78
}
78
}
79
 
79
 
80
/****************************************************/
80
/****************************************************/
Line 130... Line 130...
130
            phone_dealloc(phoneid);
130
            phone_dealloc(phoneid);
131
        } else {
131
        } else {
132
            /* The connection was accepted */
132
            /* The connection was accepted */
133
            phone_connect(phoneid,&answer->sender->answerbox);
133
            phone_connect(phoneid, &answer->sender->answerbox);
134
            /* Set 'phone identification' as arg3 of response */
134
            /* Set 'phone identification' as arg3 of response */
-
 
135
            IPC_SET_ARG3(answer->data,
135
            IPC_SET_ARG3(answer->data, (unative_t)&TASK->phones[phoneid]);
136
                (unative_t) &TASK->phones[phoneid]);
136
        }
137
        }
137
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
138
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
138
        /* If the users accepted call, connect */
139
        /* If the users accepted call, connect */
139
        if (!IPC_GET_RETVAL(answer->data)) {
140
        if (!IPC_GET_RETVAL(answer->data)) {
140
            ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata),
141
            ipc_phone_connect((phone_t *) IPC_GET_ARG3(*olddata),
141
                      &TASK->answerbox);
142
                &TASK->answerbox);
142
        }
143
        }
143
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_SEND) {
144
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_SEND) {
-
 
145
        if (!IPC_GET_RETVAL(answer->data)) {
144
        if (!IPC_GET_RETVAL(answer->data)) { /* Accepted, handle as_area receipt */
146
            /* Accepted, handle as_area receipt */
145
            ipl_t ipl;
147
            ipl_t ipl;
146
            int rc;
148
            int rc;
147
            as_t *as;
149
            as_t *as;
148
           
150
           
149
            ipl = interrupts_disable();
151
            ipl = interrupts_disable();
150
            spinlock_lock(&answer->sender->lock);
152
            spinlock_lock(&answer->sender->lock);
151
            as = answer->sender->as;
153
            as = answer->sender->as;
152
            spinlock_unlock(&answer->sender->lock);
154
            spinlock_unlock(&answer->sender->lock);
153
            interrupts_restore(ipl);
155
            interrupts_restore(ipl);
154
           
156
           
155
            rc = as_area_share(as, IPC_GET_ARG1(*olddata), IPC_GET_ARG2(*olddata),
157
            rc = as_area_share(as, IPC_GET_ARG1(*olddata),
-
 
158
                IPC_GET_ARG2(*olddata), AS,
156
                       AS, IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
159
                IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
157
            IPC_SET_RETVAL(answer->data, rc);
160
            IPC_SET_RETVAL(answer->data, rc);
158
            return rc;
161
            return rc;
159
        }
162
        }
160
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_RECV) {
163
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_RECV) {
161
        if (!IPC_GET_RETVAL(answer->data)) {
164
        if (!IPC_GET_RETVAL(answer->data)) {
Line 167... Line 170...
167
            spinlock_lock(&answer->sender->lock);
170
            spinlock_lock(&answer->sender->lock);
168
            as = answer->sender->as;
171
            as = answer->sender->as;
169
            spinlock_unlock(&answer->sender->lock);
172
            spinlock_unlock(&answer->sender->lock);
170
            interrupts_restore(ipl);
173
            interrupts_restore(ipl);
171
           
174
           
172
            rc = as_area_share(AS, IPC_GET_ARG1(answer->data), IPC_GET_ARG2(*olddata),
175
            rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
173
                       as, IPC_GET_ARG1(*olddata), IPC_GET_ARG2(answer->data));
176
                IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata),
-
 
177
                IPC_GET_ARG2(answer->data));
174
            IPC_SET_RETVAL(answer->data, rc);
178
            IPC_SET_RETVAL(answer->data, rc);
175
        }
179
        }
176
    }
180
    }
177
    return 0;
181
    return 0;
178
}
182
}
Line 215... Line 219...
215
 */
219
 */
216
 
220
 
217
/** Do basic kernel processing of received call answer */
221
/** Do basic kernel processing of received call answer */
218
static void process_answer(call_t *call)
222
static void process_answer(call_t *call)
219
{
223
{
220
    if (IPC_GET_RETVAL(call->data) == EHANGUP && \
224
    if (IPC_GET_RETVAL(call->data) == EHANGUP &&
221
        call->flags & IPC_CALL_FORWARDED)
225
        (call->flags & IPC_CALL_FORWARDED))
222
        IPC_SET_RETVAL(call->data, EFORWARD);
226
        IPC_SET_RETVAL(call->data, EFORWARD);
223
 
227
 
224
    if (call->flags & IPC_CALL_CONN_ME_TO) {
228
    if (call->flags & IPC_CALL_CONN_ME_TO) {
225
        if (IPC_GET_RETVAL(call->data))
229
        if (IPC_GET_RETVAL(call->data))
226
            phone_dealloc(call->priv);
230
            phone_dealloc(call->priv);
Line 285... Line 289...
285
    phone_t *phone;
289
    phone_t *phone;
286
    int res;
290
    int res;
287
    int rc;
291
    int rc;
288
 
292
 
289
    ipc_call_static_init(&call);
293
    ipc_call_static_init(&call);
290
    rc = copy_from_uspace(&call.data.args, &question->args, sizeof(call.data.args));
294
    rc = copy_from_uspace(&call.data.args, &question->args,
-
 
295
        sizeof(call.data.args));
291
    if (rc != 0)
296
    if (rc != 0)
292
        return (unative_t) rc;
297
        return (unative_t) rc;
293
 
298
 
294
    GET_CHECK_PHONE(phone, phoneid, return ENOENT);
299
    GET_CHECK_PHONE(phone, phoneid, return ENOENT);
295
 
300
 
Line 365... Line 370...
365
        return IPC_CALLRET_TEMPORARY;
370
        return IPC_CALLRET_TEMPORARY;
366
 
371
 
367
    GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
372
    GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
368
 
373
 
369
    call = ipc_call_alloc(0);
374
    call = ipc_call_alloc(0);
370
    rc = copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args));
375
    rc = copy_from_uspace(&call->data.args, &data->args,
-
 
376
        sizeof(call->data.args));
371
    if (rc != 0) {
377
    if (rc != 0) {
372
        ipc_call_free(call);
378
        ipc_call_free(call);
373
        return (unative_t) rc;
379
        return (unative_t) rc;
374
    }
380
    }
375
    if (!(res=request_preprocess(call)))
381
    if (!(res = request_preprocess(call)))
Line 506... Line 512...
506
    return 0;
512
    return 0;
507
}
513
}
508
 
514
 
509
/** Wait for incoming ipc call or answer
515
/** Wait for incoming ipc call or answer
510
 *
516
 *
511
 * @param calldata Pointer to buffer where the call/answer data is stored
517
 * @param calldata  Pointer to buffer where the call/answer data is stored.
512
 * @param usec Timeout. See waitq_sleep_timeout() for explanation.
518
 * @param usec      Timeout. See waitq_sleep_timeout() for explanation.
513
 * @param flags Select mode of sleep operation. See waitq_sleep_timeout() for explanation.
519
 * @param flags     Select mode of sleep operation. See waitq_sleep_timeout()
-
 
520
 *          for explanation.
514
 *
521
 *
515
 * @return Callid, if callid & 1, then the call is answer
522
 * @return Callid, if callid & 1, then the call is answer
516
 */
523
 */
517
unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int flags)
524
unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int flags)
518
{
525
{
519
    call_t *call;
526
    call_t *call;
520
 
527
 
521
restart:   
528
restart:   
522
    call = ipc_wait_for_call(&TASK->answerbox, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE);
529
    call = ipc_wait_for_call(&TASK->answerbox, usec,
-
 
530
        flags | SYNCH_FLAGS_INTERRUPTIBLE);
523
    if (!call)
531
    if (!call)
524
        return 0;
532
        return 0;
525
 
533
 
526
    if (call->flags & IPC_CALL_NOTIF) {
534
    if (call->flags & IPC_CALL_NOTIF) {
527
        ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
535
        ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
Line 572... Line 580...
572
 * @param method Method to be associated with the notification.
580
 * @param method Method to be associated with the notification.
573
 * @param ucode Uspace pointer to the top-half pseudocode.
581
 * @param ucode Uspace pointer to the top-half pseudocode.
574
 *
582
 *
575
 * @return EPERM or a return code returned by ipc_irq_register().
583
 * @return EPERM or a return code returned by ipc_irq_register().
576
 */
584
 */
577
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method, irq_code_t *ucode)
585
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
-
 
586
    irq_code_t *ucode)
578
{
587
{
579
    if (!(cap_get(TASK) & CAP_IRQ_REG))
588
    if (!(cap_get(TASK) & CAP_IRQ_REG))
580
        return EPERM;
589
        return EPERM;
581
 
590
 
582
    return ipc_irq_register(&TASK->answerbox, inr, devno, method, ucode);
591
    return ipc_irq_register(&TASK->answerbox, inr, devno, method, ucode);