Subversion Repositories HelenOS-historic

Rev

Rev 1063 | Rev 1084 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1063 Rev 1072
Line 33... Line 33...
33
#include <mm/page.h>
33
#include <mm/page.h>
34
#include <memstr.h>
34
#include <memstr.h>
35
#include <debug.h>
35
#include <debug.h>
36
#include <ipc/ipc.h>
36
#include <ipc/ipc.h>
37
#include <ipc/sysipc.h>
37
#include <ipc/sysipc.h>
-
 
38
#include <ipc/ipcrsc.h>
38
 
39
 
39
 
40
 
40
#include <print.h>
41
#include <print.h>
41
#include <arch.h>
42
#include <arch.h>
42
#include <proc/thread.h>
43
#include <proc/thread.h>
Line 62... Line 63...
62
static inline int is_forwardable(__native method)
63
static inline int is_forwardable(__native method)
63
{
64
{
64
    return 1;
65
    return 1;
65
}
66
}
66
 
67
 
67
/** Find call_t * in call table according to callid
-
 
68
 *
-
 
69
 * @return NULL on not found, otherwise pointer to call structure
-
 
70
 */
-
 
71
static inline call_t * get_call(__native callid)
-
 
72
{
-
 
73
    /* TODO: Traverse list of dispatched calls and find one */
-
 
74
    /* TODO: locking of call, ripping it from dispatched calls etc.  */
-
 
75
    return (call_t *) callid;
-
 
76
}
-
 
77
 
-
 
78
/** Return pointer to phone identified by phoneid or NULL if non-existent */
-
 
79
static phone_t * get_phone(__native phoneid)
-
 
80
{
-
 
81
    phone_t *phone;
-
 
82
 
-
 
83
    if (phoneid >= IPC_MAX_PHONES)
-
 
84
        return NULL;
-
 
85
 
-
 
86
    phone = &TASK->phones[phoneid];
-
 
87
    if (!phone->callee)
-
 
88
        return NULL;
-
 
89
    return phone;
-
 
90
}
-
 
91
 
-
 
92
/** Allocate new phone slot in current TASK structure */
-
 
93
static int phone_alloc(void)
-
 
94
{
-
 
95
    int i;
-
 
96
 
-
 
97
    spinlock_lock(&TASK->lock);
-
 
98
   
-
 
99
    for (i=0; i < IPC_MAX_PHONES; i++) {
-
 
100
        if (!TASK->phones[i].busy) {
-
 
101
            TASK->phones[i].busy = 1;
-
 
102
            break;
-
 
103
        }
-
 
104
    }
-
 
105
    spinlock_unlock(&TASK->lock);
-
 
106
 
-
 
107
    if (i >= IPC_MAX_PHONES)
-
 
108
        return -1;
-
 
109
    return i;
-
 
110
}
-
 
111
 
-
 
112
/** Disconnect phone */
-
 
113
static void phone_dealloc(int phoneid)
-
 
114
{
-
 
115
    spinlock_lock(&TASK->lock);
-
 
116
 
-
 
117
    ASSERT(TASK->phones[phoneid].busy);
-
 
118
 
-
 
119
    if (TASK->phones[phoneid].callee)
-
 
120
        ipc_phone_destroy(&TASK->phones[phoneid]);
-
 
121
 
-
 
122
    TASK->phones[phoneid].busy = 0;
-
 
123
    spinlock_unlock(&TASK->lock);
-
 
124
}
-
 
125
 
-
 
126
static void phone_connect(int phoneid, answerbox_t *box)
-
 
127
{
-
 
128
    phone_t *phone = &TASK->phones[phoneid];
-
 
129
   
-
 
130
    ipc_phone_connect(phone, box);
-
 
131
}
-
 
132
 
-
 
133
/****************************************************/
68
/****************************************************/
134
/* Functions that preprocess answer before sending
69
/* Functions that preprocess answer before sending
135
 * it to the recepient
70
 * it to the recepient
136
 */
71
 */
137
 
72
 
Line 210... Line 145...
210
                __native arg1, __native *data)
145
                __native arg1, __native *data)
211
{
146
{
212
    call_t call;
147
    call_t call;
213
    phone_t *phone;
148
    phone_t *phone;
214
 
149
 
215
    phone = get_phone(phoneid);
-
 
216
    if (!phone)
-
 
217
        return ENOENT;
-
 
218
 
-
 
219
    if (is_system_method(method))
150
    if (is_system_method(method))
220
        return EPERM;
151
        return EPERM;
221
 
152
 
-
 
153
    phone = get_phone_and_lock(phoneid);
-
 
154
    if (!phone)
-
 
155
        return ENOENT;
-
 
156
 
222
    ipc_call_init(&call);
157
    ipc_call_init(&call);
223
    IPC_SET_METHOD(call.data, method);
158
    IPC_SET_METHOD(call.data, method);
224
    IPC_SET_ARG1(call.data, arg1);
159
    IPC_SET_ARG1(call.data, arg1);
225
   
160
   
226
    ipc_call_sync(phone, &call);
161
    ipc_call_sync(phone, &call);
Line 235... Line 170...
235
               __native *reply)
170
               __native *reply)
236
{
171
{
237
    call_t call;
172
    call_t call;
238
    phone_t *phone;
173
    phone_t *phone;
239
 
174
 
240
    phone = get_phone(phoneid);
-
 
241
    if (!phone)
-
 
242
        return ENOENT;
-
 
243
 
-
 
244
    ipc_call_init(&call);
175
    ipc_call_init(&call);
245
    copy_from_uspace(&call.data, question, sizeof(call.data));
176
    copy_from_uspace(&call.data, question, sizeof(call.data));
246
 
177
 
247
    if (is_system_method(IPC_GET_METHOD(call.data)))
178
    if (is_system_method(IPC_GET_METHOD(call.data)))
248
        return EPERM;
179
        return EPERM;
249
   
180
   
-
 
181
    phone = get_phone_and_lock(phoneid);
-
 
182
    if (!phone)
-
 
183
        return ENOENT;
-
 
184
 
250
    ipc_call_sync(phone, &call);
185
    ipc_call_sync(phone, &call);
251
 
186
 
252
    copy_to_uspace(reply, &call.data, sizeof(call.data));
187
    copy_to_uspace(reply, &call.data, sizeof(call.data));
253
 
188
 
254
    return 0;
189
    return 0;
Line 276... Line 211...
276
                 __native arg1, __native arg2)
211
                 __native arg1, __native arg2)
277
{
212
{
278
    call_t *call;
213
    call_t *call;
279
    phone_t *phone;
214
    phone_t *phone;
280
 
215
 
281
    phone = get_phone(phoneid);
-
 
282
    if (!phone)
-
 
283
        return IPC_CALLRET_FATAL;
-
 
284
 
-
 
285
    if (is_system_method(method))
216
    if (is_system_method(method))
286
        return IPC_CALLRET_FATAL;
217
        return IPC_CALLRET_FATAL;
287
 
218
 
288
    if (check_call_limit())
219
    if (check_call_limit())
289
        return IPC_CALLRET_TEMPORARY;
220
        return IPC_CALLRET_TEMPORARY;
290
 
221
 
-
 
222
    phone = get_phone_and_lock(phoneid);
-
 
223
    if (!phone)
-
 
224
        return IPC_CALLRET_FATAL;
-
 
225
 
291
    call = ipc_call_alloc();
226
    call = ipc_call_alloc();
292
    IPC_SET_METHOD(call->data, method);
227
    IPC_SET_METHOD(call->data, method);
293
    IPC_SET_ARG1(call->data, arg1);
228
    IPC_SET_ARG1(call->data, arg1);
294
    IPC_SET_ARG2(call->data, arg2);
229
    IPC_SET_ARG2(call->data, arg2);
295
 
230
 
Line 305... Line 240...
305
__native sys_ipc_call_async(__native phoneid, __native *data)
240
__native sys_ipc_call_async(__native phoneid, __native *data)
306
{
241
{
307
    call_t *call;
242
    call_t *call;
308
    phone_t *phone;
243
    phone_t *phone;
309
 
244
 
310
    phone = get_phone(phoneid);
-
 
311
    if (!phone)
-
 
312
        return IPC_CALLRET_FATAL;
-
 
313
 
-
 
314
    if (check_call_limit())
245
    if (check_call_limit())
315
        return IPC_CALLRET_TEMPORARY;
246
        return IPC_CALLRET_TEMPORARY;
316
 
247
 
-
 
248
    phone = get_phone_and_lock(phoneid);
-
 
249
    if (!phone)
-
 
250
        return IPC_CALLRET_FATAL;
-
 
251
 
317
    call = ipc_call_alloc();
252
    call = ipc_call_alloc();
318
    copy_from_uspace(&call->data, data, sizeof(call->data));
253
    copy_from_uspace(&call->data, data, sizeof(call->data));
319
 
254
 
320
    if (is_system_method(IPC_GET_METHOD(call->data))) {
255
    if (is_system_method(IPC_GET_METHOD(call->data))) {
321
        ipc_call_free(call);
256
        ipc_call_free(call);
Line 342... Line 277...
342
 
277
 
343
    call = get_call(callid);
278
    call = get_call(callid);
344
    if (!call)
279
    if (!call)
345
        return ENOENT;
280
        return ENOENT;
346
 
281
 
347
    phone = get_phone(phoneid);
282
    phone = get_phone_and_lock(phoneid);
348
    if (!phone) {
283
    if (!phone) {
349
        IPC_SET_RETVAL(call->data, EFORWARD);
284
        IPC_SET_RETVAL(call->data, EFORWARD);
350
        ipc_answer(&TASK->answerbox, call);
285
        ipc_answer(&TASK->answerbox, call);
351
        return ENOENT;
286
        return ENOENT;
352
    }
287
    }
Line 434... Line 369...
434
                   __native arg2, task_id_t *taskid)
369
                   __native arg2, task_id_t *taskid)
435
{
370
{
436
    call_t call;
371
    call_t call;
437
    phone_t *phone;
372
    phone_t *phone;
438
 
373
 
439
    phone = get_phone(phoneid);
-
 
440
    if (!phone)
-
 
441
        return ENOENT;
-
 
442
 
-
 
443
    ipc_call_init(&call);
374
    ipc_call_init(&call);
444
    IPC_SET_METHOD(call.data, IPC_M_CONNECTTOME);
375
    IPC_SET_METHOD(call.data, IPC_M_CONNECTTOME);
445
    IPC_SET_ARG1(call.data, arg1);
376
    IPC_SET_ARG1(call.data, arg1);
446
    IPC_SET_ARG2(call.data, arg2);
377
    IPC_SET_ARG2(call.data, arg2);
447
   
378
   
-
 
379
    phone = get_phone_and_lock(phoneid);
-
 
380
    if (!phone)
-
 
381
        return ENOENT;
-
 
382
 
448
    ipc_call_sync(phone, &call);
383
    ipc_call_sync(phone, &call);
449
 
384
 
450
    if (!IPC_GET_RETVAL(call.data) && taskid)
385
    if (!IPC_GET_RETVAL(call.data) && taskid)
451
        copy_to_uspace(taskid,
386
        copy_to_uspace(taskid,
452
                   &phone->callee->task->taskid,
387
                   &phone->callee->task->taskid,
Line 464... Line 399...
464
{
399
{
465
    call_t call;
400
    call_t call;
466
    phone_t *phone;
401
    phone_t *phone;
467
    int newphid;
402
    int newphid;
468
 
403
 
469
    phone = get_phone(phoneid);
404
    phone = get_phone_and_lock(phoneid);
470
    if (!phone)
405
    if (!phone)
471
        return ENOENT;
406
        return ENOENT;
472
 
407
 
473
    newphid = phone_alloc();
408
    newphid = phone_alloc();
474
    if (newphid < 0)
409
    if (newphid < 0)