Subversion Repositories HelenOS-historic

Rev

Rev 1757 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1757 Rev 1780
Line 54... Line 54...
54
}
54
}
55
 
55
 
56
#define STRUCT_TO_USPACE(dst,src) copy_to_uspace(dst,src,sizeof(*(src)))
56
#define STRUCT_TO_USPACE(dst,src) copy_to_uspace(dst,src,sizeof(*(src)))
57
 
57
 
58
/** Return true if the method is a system method */
58
/** Return true if the method is a system method */
59
static inline int is_system_method(__native method)
59
static inline int is_system_method(unative_t method)
60
{
60
{
61
    if (method <= IPC_M_LAST_SYSTEM)
61
    if (method <= IPC_M_LAST_SYSTEM)
62
        return 1;
62
        return 1;
63
    return 0;
63
    return 0;
64
}
64
}
Line 66... Line 66...
66
/** Return true if the message with this method is forwardable
66
/** Return true if the message with this method is forwardable
67
 *
67
 *
68
 * - some system messages may be forwarded, for some of them
68
 * - some system messages may be forwarded, for some of them
69
 *   it is useless
69
 *   it is useless
70
 */
70
 */
71
static inline int is_forwardable(__native method)
71
static inline int is_forwardable(unative_t method)
72
{
72
{
73
    if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND \
73
    if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND \
74
        || method == IPC_M_AS_AREA_RECV)
74
        || method == IPC_M_AS_AREA_RECV)
75
        return 0; /* This message is meant only for the receiver */
75
        return 0; /* This message is meant only for the receiver */
76
    return 1;
76
    return 1;
Line 129... Line 129...
129
            phone_dealloc(phoneid);
129
            phone_dealloc(phoneid);
130
        } else {
130
        } else {
131
            /* The connection was accepted */
131
            /* The connection was accepted */
132
            phone_connect(phoneid,&answer->sender->answerbox);
132
            phone_connect(phoneid,&answer->sender->answerbox);
133
            /* Set 'phone identification' as arg3 of response */
133
            /* Set 'phone identification' as arg3 of response */
134
            IPC_SET_ARG3(answer->data, (__native)&TASK->phones[phoneid]);
134
            IPC_SET_ARG3(answer->data, (unative_t)&TASK->phones[phoneid]);
135
        }
135
        }
136
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
136
    } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
137
        /* If the users accepted call, connect */
137
        /* If the users accepted call, connect */
138
        if (!IPC_GET_RETVAL(answer->data)) {
138
        if (!IPC_GET_RETVAL(answer->data)) {
139
            ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata),
139
            ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata),
Line 189... Line 189...
189
    case IPC_M_CONNECT_ME_TO:
189
    case IPC_M_CONNECT_ME_TO:
190
        newphid = phone_alloc();
190
        newphid = phone_alloc();
191
        if (newphid < 0)
191
        if (newphid < 0)
192
            return ELIMIT;
192
            return ELIMIT;
193
        /* Set arg3 for server */
193
        /* Set arg3 for server */
194
        IPC_SET_ARG3(call->data, (__native)&TASK->phones[newphid]);
194
        IPC_SET_ARG3(call->data, (unative_t)&TASK->phones[newphid]);
195
        call->flags |= IPC_CALL_CONN_ME_TO;
195
        call->flags |= IPC_CALL_CONN_ME_TO;
196
        call->private = newphid;
196
        call->private = newphid;
197
        break;
197
        break;
198
    case IPC_M_AS_AREA_SEND:
198
    case IPC_M_AS_AREA_SEND:
199
        size = as_get_size(IPC_GET_ARG1(call->data));
199
        size = as_get_size(IPC_GET_ARG1(call->data));
Line 251... Line 251...
251
/** Send a call over IPC, wait for reply, return to user
251
/** Send a call over IPC, wait for reply, return to user
252
 *
252
 *
253
 * @return Call identification, returns -1 on fatal error,
253
 * @return Call identification, returns -1 on fatal error,
254
           -2 on 'Too many async request, handle answers first
254
           -2 on 'Too many async request, handle answers first
255
 */
255
 */
256
__native sys_ipc_call_sync_fast(__native phoneid, __native method,
256
unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method,
257
                __native arg1, ipc_data_t *data)
257
                unative_t arg1, ipc_data_t *data)
258
{
258
{
259
    call_t call;
259
    call_t call;
260
    phone_t *phone;
260
    phone_t *phone;
261
    int res;
261
    int res;
262
 
262
 
Line 275... Line 275...
275
 
275
 
276
    return 0;
276
    return 0;
277
}
277
}
278
 
278
 
279
/** Synchronous IPC call allowing to send whole message */
279
/** Synchronous IPC call allowing to send whole message */
280
__native sys_ipc_call_sync(__native phoneid, ipc_data_t *question,
280
unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question,
281
               ipc_data_t *reply)
281
               ipc_data_t *reply)
282
{
282
{
283
    call_t call;
283
    call_t call;
284
    phone_t *phone;
284
    phone_t *phone;
285
    int res;
285
    int res;
286
    int rc;
286
    int rc;
287
 
287
 
288
    ipc_call_static_init(&call);
288
    ipc_call_static_init(&call);
289
    rc = copy_from_uspace(&call.data.args, &question->args, sizeof(call.data.args));
289
    rc = copy_from_uspace(&call.data.args, &question->args, sizeof(call.data.args));
290
    if (rc != 0)
290
    if (rc != 0)
291
        return (__native) rc;
291
        return (unative_t) rc;
292
 
292
 
293
    GET_CHECK_PHONE(phone, phoneid, return ENOENT);
293
    GET_CHECK_PHONE(phone, phoneid, return ENOENT);
294
 
294
 
295
    if (!(res=request_preprocess(&call))) {
295
    if (!(res=request_preprocess(&call))) {
296
        ipc_call_sync(phone, &call);
296
        ipc_call_sync(phone, &call);
Line 321... Line 321...
321
/** Send an asynchronous call over ipc
321
/** Send an asynchronous call over ipc
322
 *
322
 *
323
 * @return Call identification, returns -1 on fatal error,
323
 * @return Call identification, returns -1 on fatal error,
324
           -2 on 'Too many async request, handle answers first
324
           -2 on 'Too many async request, handle answers first
325
 */
325
 */
326
__native sys_ipc_call_async_fast(__native phoneid, __native method,
326
unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method,
327
                 __native arg1, __native arg2)
327
                 unative_t arg1, unative_t arg2)
328
{
328
{
329
    call_t *call;
329
    call_t *call;
330
    phone_t *phone;
330
    phone_t *phone;
331
    int res;
331
    int res;
332
 
332
 
Line 344... Line 344...
344
    if (!(res=request_preprocess(call)))
344
    if (!(res=request_preprocess(call)))
345
        ipc_call(phone, call);
345
        ipc_call(phone, call);
346
    else
346
    else
347
        ipc_backsend_err(phone, call, res);
347
        ipc_backsend_err(phone, call, res);
348
 
348
 
349
    return (__native) call;
349
    return (unative_t) call;
350
}
350
}
351
 
351
 
352
/** Synchronous IPC call allowing to send whole message
352
/** Synchronous IPC call allowing to send whole message
353
 *
353
 *
354
 * @return The same as sys_ipc_call_async
354
 * @return The same as sys_ipc_call_async
355
 */
355
 */
356
__native sys_ipc_call_async(__native phoneid, ipc_data_t *data)
356
unative_t sys_ipc_call_async(unative_t phoneid, ipc_data_t *data)
357
{
357
{
358
    call_t *call;
358
    call_t *call;
359
    phone_t *phone;
359
    phone_t *phone;
360
    int res;
360
    int res;
361
    int rc;
361
    int rc;
Line 367... Line 367...
367
 
367
 
368
    call = ipc_call_alloc(0);
368
    call = ipc_call_alloc(0);
369
    rc = copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args));
369
    rc = copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args));
370
    if (rc != 0) {
370
    if (rc != 0) {
371
        ipc_call_free(call);
371
        ipc_call_free(call);
372
        return (__native) rc;
372
        return (unative_t) rc;
373
    }
373
    }
374
    if (!(res=request_preprocess(call)))
374
    if (!(res=request_preprocess(call)))
375
        ipc_call(phone, call);
375
        ipc_call(phone, call);
376
    else
376
    else
377
        ipc_backsend_err(phone, call, res);
377
        ipc_backsend_err(phone, call, res);
378
 
378
 
379
    return (__native) call;
379
    return (unative_t) call;
380
}
380
}
381
 
381
 
382
/** Forward received call to another destination
382
/** Forward received call to another destination
383
 *
383
 *
384
 * The arg1 and arg2 are changed in the forwarded message
384
 * The arg1 and arg2 are changed in the forwarded message
385
 *
385
 *
386
 * Warning: If implementing non-fast version, make sure that
386
 * Warning: If implementing non-fast version, make sure that
387
 *          arg3 is not rewritten for certain system IPC
387
 *          arg3 is not rewritten for certain system IPC
388
 */
388
 */
389
__native sys_ipc_forward_fast(__native callid, __native phoneid,
389
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
390
                  __native method, __native arg1)
390
                  unative_t method, unative_t arg1)
391
{
391
{
392
    call_t *call;
392
    call_t *call;
393
    phone_t *phone;
393
    phone_t *phone;
394
 
394
 
395
    call = get_call(callid);
395
    call = get_call(callid);
Line 426... Line 426...
426
 
426
 
427
    return ipc_forward(call, phone, &TASK->answerbox);
427
    return ipc_forward(call, phone, &TASK->answerbox);
428
}
428
}
429
 
429
 
430
/** Send IPC answer */
430
/** Send IPC answer */
431
__native sys_ipc_answer_fast(__native callid, __native retval,
431
unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval,
432
                 __native arg1, __native arg2)
432
                 unative_t arg1, unative_t arg2)
433
{
433
{
434
    call_t *call;
434
    call_t *call;
435
    ipc_data_t saved_data;
435
    ipc_data_t saved_data;
436
    int saveddata = 0;
436
    int saveddata = 0;
437
    int rc;
437
    int rc;
Line 457... Line 457...
457
    ipc_answer(&TASK->answerbox, call);
457
    ipc_answer(&TASK->answerbox, call);
458
    return rc;
458
    return rc;
459
}
459
}
460
 
460
 
461
/** Send IPC answer */
461
/** Send IPC answer */
462
__native sys_ipc_answer(__native callid, ipc_data_t *data)
462
unative_t sys_ipc_answer(unative_t callid, ipc_data_t *data)
463
{
463
{
464
    call_t *call;
464
    call_t *call;
465
    ipc_data_t saved_data;
465
    ipc_data_t saved_data;
466
    int saveddata = 0;
466
    int saveddata = 0;
467
    int rc;
467
    int rc;
Line 491... Line 491...
491
}
491
}
492
 
492
 
493
/** Hang up the phone
493
/** Hang up the phone
494
 *
494
 *
495
 */
495
 */
496
__native sys_ipc_hangup(int phoneid)
496
unative_t sys_ipc_hangup(int phoneid)
497
{
497
{
498
    phone_t *phone;
498
    phone_t *phone;
499
 
499
 
500
    GET_CHECK_PHONE(phone, phoneid, return ENOENT);
500
    GET_CHECK_PHONE(phone, phoneid, return ENOENT);
501
 
501
 
Line 511... Line 511...
511
 * @param usec Timeout. See waitq_sleep_timeout() for explanation.
511
 * @param usec Timeout. See waitq_sleep_timeout() for explanation.
512
 * @param flags Select mode of sleep operation. See waitq_sleep_timeout() for explanation.
512
 * @param flags Select mode of sleep operation. See waitq_sleep_timeout() for explanation.
513
 *
513
 *
514
 * @return Callid, if callid & 1, then the call is answer
514
 * @return Callid, if callid & 1, then the call is answer
515
 */
515
 */
516
__native sys_ipc_wait_for_call(ipc_data_t *calldata, __u32 usec, int flags)
516
unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int flags)
517
{
517
{
518
    call_t *call;
518
    call_t *call;
519
 
519
 
520
restart:   
520
restart:   
521
    call = ipc_wait_for_call(&TASK->answerbox, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE);
521
    call = ipc_wait_for_call(&TASK->answerbox, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE);
Line 530... Line 530...
530
       
530
       
531
        STRUCT_TO_USPACE(calldata, &call->data);
531
        STRUCT_TO_USPACE(calldata, &call->data);
532
 
532
 
533
        ipc_call_free(call);
533
        ipc_call_free(call);
534
       
534
       
535
        return ((__native)call) | IPC_CALLID_NOTIFICATION;
535
        return ((unative_t)call) | IPC_CALLID_NOTIFICATION;
536
    }
536
    }
537
 
537
 
538
    if (call->flags & IPC_CALL_ANSWERED) {
538
    if (call->flags & IPC_CALL_ANSWERED) {
539
        process_answer(call);
539
        process_answer(call);
540
 
540
 
Line 548... Line 548...
548
        }
548
        }
549
 
549
 
550
        STRUCT_TO_USPACE(&calldata->args, &call->data.args);
550
        STRUCT_TO_USPACE(&calldata->args, &call->data.args);
551
        ipc_call_free(call);
551
        ipc_call_free(call);
552
 
552
 
553
        return ((__native)call) | IPC_CALLID_ANSWERED;
553
        return ((unative_t)call) | IPC_CALLID_ANSWERED;
554
    }
554
    }
555
 
555
 
556
    if (process_request(&TASK->answerbox, call))
556
    if (process_request(&TASK->answerbox, call))
557
        goto restart;
557
        goto restart;
558
 
558
 
559
    /* Include phone address('id') of the caller in the request,
559
    /* Include phone address('id') of the caller in the request,
560
     * copy whole call->data, not only call->data.args */
560
     * copy whole call->data, not only call->data.args */
561
    if (STRUCT_TO_USPACE(calldata, &call->data)) {
561
    if (STRUCT_TO_USPACE(calldata, &call->data)) {
562
        return 0;
562
        return 0;
563
    }
563
    }
564
    return (__native)call;
564
    return (unative_t)call;
565
}
565
}
566
 
566
 
567
/** Connect irq handler to task */
567
/** Connect irq handler to task */
568
__native sys_ipc_register_irq(int irq, irq_code_t *ucode)
568
unative_t sys_ipc_register_irq(int irq, irq_code_t *ucode)
569
{
569
{
570
    if (!(cap_get(TASK) & CAP_IRQ_REG))
570
    if (!(cap_get(TASK) & CAP_IRQ_REG))
571
        return EPERM;
571
        return EPERM;
572
 
572
 
573
    if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL)
573
    if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL)
574
        return (__native) ELIMIT;
574
        return (unative_t) ELIMIT;
575
   
575
   
576
    irq_ipc_bind_arch(irq);
576
    irq_ipc_bind_arch(irq);
577
 
577
 
578
    return ipc_irq_register(&TASK->answerbox, irq, ucode);
578
    return ipc_irq_register(&TASK->answerbox, irq, ucode);
579
}
579
}
580
 
580
 
581
/* Disconnect irq handler from task */
581
/* Disconnect irq handler from task */
582
__native sys_ipc_unregister_irq(int irq)
582
unative_t sys_ipc_unregister_irq(int irq)
583
{
583
{
584
    if (!(cap_get(TASK) & CAP_IRQ_REG))
584
    if (!(cap_get(TASK) & CAP_IRQ_REG))
585
        return EPERM;
585
        return EPERM;
586
 
586
 
587
    if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL)
587
    if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL)
588
        return (__native) ELIMIT;
588
        return (unative_t) ELIMIT;
589
 
589
 
590
    ipc_irq_unregister(&TASK->answerbox, irq);
590
    ipc_irq_unregister(&TASK->answerbox, irq);
591
 
591
 
592
    return 0;
592
    return 0;
593
}
593
}