Subversion Repositories HelenOS

Rev

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

Rev 959 Rev 965
Line 58... Line 58...
58
/** Send a call over IPC, wait for reply, return to user
58
/** Send a call over IPC, wait for reply, return to user
59
 *
59
 *
60
 * @return Call identification, returns -1 on fatal error,
60
 * @return Call identification, returns -1 on fatal error,
61
           -2 on 'Too many async request, handle answers first
61
           -2 on 'Too many async request, handle answers first
62
 */
62
 */
63
static __native sys_ipc_call_sync(__native phoneid, __native arg1,
63
static __native sys_ipc_call_sync(__native phoneid, __native method,
64
                   __native arg2, __native *respdata)
64
                   __native arg1, __native *data)
65
{
65
{
66
    call_t *call;
66
    call_t call;
67
    phone_t *phone;
67
    phone_t *phone;
68
    /* Special answerbox for synchronous messages */
68
    /* Special answerbox for synchronous messages */
69
 
69
 
70
    if (phoneid >= IPC_MAX_PHONES)
70
    if (phoneid >= IPC_MAX_PHONES)
71
        return -ENOENT;
71
        return IPC_CALLRET_FATAL;
72
 
72
 
73
    phone = &TASK->phones[phoneid];
73
    phone = &TASK->phones[phoneid];
74
    if (!phone->callee)
74
    if (!phone->callee)
75
        return -ENOENT;
75
        return IPC_CALLRET_FATAL;
76
 
76
 
77
    call = ipc_call_alloc();
77
    ipc_call_init(&call);
-
 
78
    IPC_SET_METHOD(call.data, method);
78
    call->data[0] = arg1;
79
    IPC_SET_ARG1(call.data, arg1);
-
 
80
   
-
 
81
    ipc_call_sync(phone, &call);
-
 
82
 
-
 
83
    copy_to_uspace(data, &call.data, sizeof(call.data));
-
 
84
 
-
 
85
    return 0;
-
 
86
}
-
 
87
 
-
 
88
static __native sys_ipc_call_sync_medium(__native phoneid, __native *data)
-
 
89
{
79
    call->data[1] = arg2;
90
    call_t call;
-
 
91
    phone_t *phone;
-
 
92
    /* Special answerbox for synchronous messages */
-
 
93
 
-
 
94
    if (phoneid >= IPC_MAX_PHONES)
-
 
95
        return IPC_CALLRET_FATAL;
-
 
96
 
-
 
97
    phone = &TASK->phones[phoneid];
-
 
98
    if (!phone->callee)
-
 
99
        return IPC_CALLRET_FATAL;
-
 
100
 
-
 
101
    ipc_call_init(&call);
-
 
102
    copy_from_uspace(&call.data, data, sizeof(call.data));
80
   
103
   
81
    ipc_call_sync(phone, call);
104
    ipc_call_sync(phone, &call);
82
 
105
 
83
    copy_to_uspace(respdata, &call->data, sizeof(__native) * IPC_CALL_LEN);
106
    copy_to_uspace(data, &call.data, sizeof(call.data));
84
 
107
 
85
    return 0;
108
    return 0;
86
}
109
}
87
 
110
 
-
 
111
 
88
/** Send an asynchronous call over ipc
112
/** Send an asynchronous call over ipc
89
 *
113
 *
90
 * @return Call identification, returns -1 on fatal error,
114
 * @return Call identification, returns -1 on fatal error,
91
           -2 on 'Too many async request, handle answers first
115
           -2 on 'Too many async request, handle answers first
92
 */
116
 */
93
static __native sys_ipc_call_async(__native phoneid, __native arg1,
117
static __native sys_ipc_call_async(__native phoneid, __native method,
94
                   __native arg2)
118
                   __native arg1, __native arg2)
95
{
119
{
96
    call_t *call;
120
    call_t *call;
97
    phone_t *phone;
121
    phone_t *phone;
98
 
122
 
99
    if (phoneid >= IPC_MAX_PHONES)
123
    if (phoneid >= IPC_MAX_PHONES)
100
        return -ENOENT;
124
        return IPC_CALLRET_FATAL;
101
 
125
 
102
    phone = &TASK->phones[phoneid];
126
    phone = &TASK->phones[phoneid];
103
    if (!phone->callee)
127
    if (!phone->callee)
104
        return -ENOENT;
128
        return IPC_CALLRET_FATAL;
105
 
-
 
106
 
129
 
107
    /* TODO: Check that we did not exceed system imposed maximum
130
    /* TODO: Check that we did not exceed system imposed maximum
108
     * of asynchrnously sent messages
131
     * of asynchrnously sent messages
109
     * - the userspace should be able to handle it correctly
132
     * - the userspace should be able to handle it correctly
110
     */
133
     */
111
    call = ipc_call_alloc();
134
    call = ipc_call_alloc();
-
 
135
    IPC_SET_METHOD(call->data, method);
112
    call->data[0] = arg1;
136
    IPC_SET_ARG1(call->data, arg1);
113
    call->data[1] = arg2;
137
    IPC_SET_ARG2(call->data, arg2);
-
 
138
 
114
    ipc_call(phone, call);
139
    ipc_call(phone, call);
115
 
140
 
116
    return (__native) call;
141
    return (__native) call;
117
}
142
}
118
 
143
 
119
/** Send IPC answer */
144
/** Send IPC answer */
120
static __native sys_ipc_answer(__native callid, __native arg1, __native arg2)
145
static __native sys_ipc_answer(__native callid, __native retval, __native arg1,
-
 
146
                   __native arg2)
121
{
147
{
122
    call_t *call;
148
    call_t *call;
123
 
149
 
124
    /* Check that the user is not sending us answer callid */
150
    /* Check that the user is not sending us answer callid */
125
    ASSERT(! (callid & 1));
151
    ASSERT(! (callid & 1));
126
    /* TODO: Check that the callid is in the dispatch table */
152
    /* TODO: Check that the callid is in the dispatch table */
127
    call = (call_t *) callid;
153
    call = (call_t *) callid;
128
 
154
 
-
 
155
    IPC_SET_RETVAL(call->data, retval);
129
    call->data[0] = arg1;
156
    IPC_SET_ARG1(call->data, arg1);
130
    call->data[1] = arg2;
157
    IPC_SET_ARG2(call->data, arg2);
131
 
158
 
132
    ipc_answer(&TASK->answerbox, call);
159
    ipc_answer(&TASK->answerbox, call);
133
    return 0;
160
    return 0;
134
}
161
}
135
 
162
 
Line 142... Line 169...
142
static __native sys_ipc_wait_for_call(__native *calldata, __native flags)
169
static __native sys_ipc_wait_for_call(__native *calldata, __native flags)
143
{
170
{
144
    call_t *call;
171
    call_t *call;
145
   
172
   
146
    call = ipc_wait_for_call(&TASK->answerbox, flags);
173
    call = ipc_wait_for_call(&TASK->answerbox, flags);
147
    copy_to_uspace(calldata, &call->data, sizeof(__native) * IPC_CALL_LEN);
-
 
148
 
174
 
-
 
175
    copy_to_uspace(calldata, &call->data, sizeof(call->data));
149
    if (call->flags & IPC_CALL_ANSWERED)
176
    if (call->flags & IPC_CALL_ANSWERED) {
-
 
177
        ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
-
 
178
        ipc_call_free(call);
150
        return ((__native)call) | 1;
179
        return ((__native)call) | IPC_CALLID_ANSWERED;
-
 
180
    }
151
    return (__native)call;
181
    return (__native)call;
152
}
182
}
153
 
183
 
154
 
184
 
155
syshandler_t syscall_table[SYSCALL_END] = {
185
syshandler_t syscall_table[SYSCALL_END] = {
156
    sys_ctl,
186
    sys_ctl,
157
    sys_io,
187
    sys_io,
158
    sys_ipc_call_sync,
188
    sys_ipc_call_sync,
-
 
189
    sys_ipc_call_sync_medium,
159
    sys_ipc_call_async,
190
    sys_ipc_call_async,
160
    sys_ipc_answer,
191
    sys_ipc_answer,
161
    sys_ipc_wait_for_call
192
    sys_ipc_wait_for_call
162
};
193
};