Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3370 → Rev 3386

/branches/network/kernel/generic/src/ipc/sysipc.c
164,11 → 164,11
{
int phoneid;
 
if (IPC_GET_RETVAL(answer->data) == EHANGUP) {
if ((native_t) IPC_GET_RETVAL(answer->data) == EHANGUP) {
/* In case of forward, hangup the forwared phone,
* not the originator
*/
spinlock_lock(&answer->data.phone->lock);
mutex_lock(&answer->data.phone->lock);
spinlock_lock(&TASK->answerbox.lock);
if (answer->data.phone->state == IPC_PHONE_CONNECTED) {
list_remove(&answer->data.phone->link);
175,7 → 175,7
answer->data.phone->state = IPC_PHONE_SLAMMED;
}
spinlock_unlock(&TASK->answerbox.lock);
spinlock_unlock(&answer->data.phone->lock);
mutex_unlock(&answer->data.phone->lock);
}
 
if (!olddata)
243,7 → 243,7
uintptr_t dst = IPC_GET_ARG1(*olddata);
size_t max_size = IPC_GET_ARG2(*olddata);
size_t size = IPC_GET_ARG2(answer->data);
if (size <= max_size) {
if (size && size <= max_size) {
/*
* Copy the destination VA so that this piece of
* information is not lost.
258,6 → 258,8
free(answer->buffer);
answer->buffer = NULL;
}
} else if (!size) {
IPC_SET_RETVAL(answer->data, EOK);
} else {
IPC_SET_RETVAL(answer->data, ELIMIT);
}
268,12 → 270,12
/* The recipient agreed to receive data. */
int rc;
uintptr_t dst;
uintptr_t size;
uintptr_t max_size;
size_t size;
size_t max_size;
 
dst = IPC_GET_ARG1(answer->data);
size = IPC_GET_ARG2(answer->data);
max_size = IPC_GET_ARG2(*olddata);
dst = (uintptr_t)IPC_GET_ARG1(answer->data);
size = (size_t)IPC_GET_ARG2(answer->data);
max_size = (size_t)IPC_GET_ARG2(*olddata);
 
if (size <= max_size) {
rc = copy_to_uspace((void *) dst,
354,7 → 356,7
*/
static void process_answer(call_t *call)
{
if (IPC_GET_RETVAL(call->data) == EHANGUP &&
if (((native_t) IPC_GET_RETVAL(call->data) == EHANGUP) &&
(call->flags & IPC_CALL_FORWARDED))
IPC_SET_RETVAL(call->data, EFORWARD);
 
424,7 → 426,7
phone_t *phone;
int res;
int rc;
 
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
ipc_call_static_init(&call);
440,7 → 442,9
IPC_SET_ARG5(call.data, 0);
 
if (!(res = request_preprocess(&call))) {
ipc_call_sync(phone, &call);
rc = ipc_call_sync(phone, &call);
if (rc != EOK)
return rc;
process_answer(&call);
} else {
IPC_SET_RETVAL(call.data, res);
478,7 → 482,9
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (!(res = request_preprocess(&call))) {
ipc_call_sync(phone, &call);
rc = ipc_call_sync(phone, &call);
if (rc != EOK)
return rc;
process_answer(&call);
} else
IPC_SET_RETVAL(call.data, res);
624,7 → 630,7
IPC_SET_RETVAL(call->data, EFORWARD);
ipc_answer(&TASK->answerbox, call);
return ENOENT;
});
});
 
if (!method_is_forwardable(IPC_GET_METHOD(call->data))) {
IPC_SET_RETVAL(call->data, EFORWARD);
/branches/network/kernel/generic/src/ipc/ipc.c
37,7 → 37,9
* First the answerbox, then the phone.
*/
 
#include <synch/synch.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <synch/waitq.h>
#include <synch/synch.h>
#include <ipc/ipc.h>
64,7 → 66,7
*/
static void _ipc_call_init(call_t *call)
{
memsetb((uintptr_t) call, sizeof(*call), 0);
memsetb(call, sizeof(*call), 0);
call->callerbox = &TASK->answerbox;
call->sender = TASK;
call->buffer = NULL;
85,7 → 87,8
call_t *call;
 
call = slab_alloc(ipc_call_slab, flags);
_ipc_call_init(call);
if (call)
_ipc_call_init(call);
 
return call;
}
117,8 → 120,9
/** Initialize an answerbox structure.
*
* @param box Answerbox structure to be initialized.
* @param task Task to which the answerbox belongs.
*/
void ipc_answerbox_init(answerbox_t *box)
void ipc_answerbox_init(answerbox_t *box, task_t *task)
{
spinlock_initialize(&box->lock, "ipc_box_lock");
spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
129,7 → 133,7
list_initialize(&box->answers);
list_initialize(&box->irq_notifs);
list_initialize(&box->irq_head);
box->task = TASK;
box->task = task;
}
 
/** Connect a phone to an answerbox.
139,7 → 143,7
*/
void ipc_phone_connect(phone_t *phone, answerbox_t *box)
{
spinlock_lock(&phone->lock);
mutex_lock(&phone->lock);
 
phone->state = IPC_PHONE_CONNECTED;
phone->callee = box;
148,7 → 152,7
list_append(&phone->link, &box->connected_phones);
spinlock_unlock(&box->lock);
 
spinlock_unlock(&phone->lock);
mutex_unlock(&phone->lock);
}
 
/** Initialize a phone structure.
157,7 → 161,7
*/
void ipc_phone_init(phone_t *phone)
{
spinlock_initialize(&phone->lock, "phone_lock");
mutex_initialize(&phone->lock, MUTEX_PASSIVE);
phone->callee = NULL;
phone->state = IPC_PHONE_FREE;
atomic_set(&phone->active_calls, 0);
167,18 → 171,23
*
* @param phone Destination kernel phone structure.
* @param request Call structure with request.
*
* @return EOK on success or EINTR if the sleep was interrupted.
*/
void ipc_call_sync(phone_t *phone, call_t *request)
int ipc_call_sync(phone_t *phone, call_t *request)
{
answerbox_t sync_box;
 
ipc_answerbox_init(&sync_box);
ipc_answerbox_init(&sync_box, TASK);
 
/* We will receive data in a special box. */
request->callerbox = &sync_box;
 
ipc_call(phone, request);
ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
SYNCH_FLAGS_INTERRUPTIBLE))
return EINTR;
return EOK;
}
 
/** Answer a message which was not dispatched and is not listed in any queue.
191,6 → 200,13
 
call->flags |= IPC_CALL_ANSWERED;
 
if (call->flags & IPC_CALL_FORWARDED) {
if (call->data.caller_phone) {
/* Demasquerade the caller phone. */
call->data.phone = call->data.caller_phone;
}
}
 
spinlock_lock(&callerbox->lock);
list_append(&call->link, &callerbox->answers);
spinlock_unlock(&callerbox->lock);
260,9 → 276,9
{
answerbox_t *box;
 
spinlock_lock(&phone->lock);
mutex_lock(&phone->lock);
if (phone->state != IPC_PHONE_CONNECTED) {
spinlock_unlock(&phone->lock);
mutex_unlock(&phone->lock);
if (call->flags & IPC_CALL_FORWARDED) {
IPC_SET_RETVAL(call->data, EFORWARD);
_ipc_answer_free_call(call);
277,7 → 293,7
box = phone->callee;
_ipc_call(phone, box, call);
spinlock_unlock(&phone->lock);
mutex_unlock(&phone->lock);
return 0;
}
 
296,11 → 312,11
answerbox_t *box;
call_t *call;
spinlock_lock(&phone->lock);
mutex_lock(&phone->lock);
if (phone->state == IPC_PHONE_FREE ||
phone->state == IPC_PHONE_HUNGUP ||
phone->state == IPC_PHONE_CONNECTING) {
spinlock_unlock(&phone->lock);
mutex_unlock(&phone->lock);
return -1;
}
box = phone->callee;
319,7 → 335,7
}
 
phone->state = IPC_PHONE_HUNGUP;
spinlock_unlock(&phone->lock);
mutex_unlock(&phone->lock);
 
return 0;
}
343,8 → 359,11
list_remove(&call->link);
spinlock_unlock(&oldbox->lock);
 
if (mode & IPC_FF_ROUTE_FROM_ME)
if (mode & IPC_FF_ROUTE_FROM_ME) {
if (!call->data.caller_phone)
call->data.caller_phone = call->data.phone;
call->data.phone = newphone;
}
 
return ipc_call(newphone, call);
}
448,7 → 467,7
while (!list_empty(&TASK->answerbox.connected_phones)) {
phone = list_get_instance(TASK->answerbox.connected_phones.next,
phone_t, link);
if (!spinlock_trylock(&phone->lock)) {
if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
spinlock_unlock(&TASK->answerbox.lock);
DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
goto restart_phones;
459,7 → 478,7
phone->state = IPC_PHONE_SLAMMED;
list_remove(&phone->link);
 
spinlock_unlock(&phone->lock);
mutex_unlock(&phone->lock);
}
 
/* Answer all messages in 'calls' and 'dispatched_calls' queues */
534,7 → 553,10
/* Print opened phones & details */
printf("PHONE:\n");
for (i = 0; i < IPC_MAX_PHONES; i++) {
spinlock_lock(&task->phones[i].lock);
if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
printf("%d: mutex busy\n", i);
continue;
}
if (task->phones[i].state != IPC_PHONE_FREE) {
printf("%d: ", i);
switch (task->phones[i].state) {
556,10 → 578,10
default:
break;
}
printf("active: %d\n",
printf("active: %ld\n",
atomic_get(&task->phones[i].active_calls));
}
spinlock_unlock(&task->phones[i].lock);
mutex_unlock(&task->phones[i].lock);
}
 
 
569,8 → 591,9
for (tmp = task->answerbox.calls.next; tmp != &task->answerbox.calls;
tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid: %p Srctask:%llu M:%d A1:%d A2:%d A3:%d "
"A4:%d A5:%d Flags:%x\n", call, call->sender->taskid,
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, call->sender->taskid,
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
578,12 → 601,13
}
/* Print answerbox - calls */
printf("ABOX - DISPATCHED CALLS:\n");
for (tmp=task->answerbox.dispatched_calls.next;
tmp != &task->answerbox.dispatched_calls;
tmp = tmp->next) {
for (tmp = task->answerbox.dispatched_calls.next;
tmp != &task->answerbox.dispatched_calls;
tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid: %p Srctask:%llu M:%d A1:%d A2:%d A3:%d "
"A4:%d A5:%d Flags:%x\n", call, call->sender->taskid,
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, call->sender->taskid,
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
594,7 → 618,8
for (tmp = task->answerbox.answers.next; tmp != &task->answerbox.answers;
tmp = tmp->next) {
call = list_get_instance(tmp, call_t, link);
printf("Callid:%p M:%d A1:%d A2:%d A3:%d A4:%d A5:%d Flags:%x\n",
printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun
" A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n",
call, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data),
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
/branches/network/kernel/generic/src/ipc/ipcrsc.c
170,7 → 170,6
int i;
 
spinlock_lock(&TASK->lock);
for (i = 0; i < IPC_MAX_PHONES; i++) {
if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
atomic_get(&TASK->phones[i].active_calls) == 0)
183,8 → 182,9
}
spinlock_unlock(&TASK->lock);
 
if (i >= IPC_MAX_PHONES)
if (i == IPC_MAX_PHONES)
return -1;
 
return i;
}
 
/branches/network/kernel/generic/src/ipc/irq.c
65,7 → 65,7
*/
static void code_execute(call_t *call, irq_code_t *code)
{
int i;
unsigned int i;
unative_t dstval = 0;
if (!code)