Changeset 9a1b20c in mainline for kernel/generic/src/ipc
- Timestamp:
- 2008-09-17T12:16:27Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fb9b0b0
- Parents:
- 06a195bc
- Location:
- kernel/generic/src/ipc
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
r06a195bc r9a1b20c 44 44 #include <synch/synch.h> 45 45 #include <ipc/ipc.h> 46 #include <ipc/ipc_kbox.h> 46 47 #include <errno.h> 47 48 #include <mm/slab.h> … … 52 53 53 54 #include <print.h> 55 #include <console/console.h> 54 56 #include <proc/thread.h> 55 57 #include <arch/interrupt.h> … … 428 430 * @param lst Head of the list to be cleaned up. 429 431 */ 430 staticvoid ipc_cleanup_call_list(link_t *lst)432 void ipc_cleanup_call_list(link_t *lst) 431 433 { 432 434 call_t *call; … … 443 445 } 444 446 447 /** Disconnects all phones connected to an answerbox. 448 * 449 * @param box Answerbox to disconnect phones from. 450 * @param notify_box If true, the answerbox will get a hangup message for 451 * each disconnected phone. 452 */ 453 void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box) 454 { 455 phone_t *phone; 456 DEADLOCK_PROBE_INIT(p_phonelck); 457 ipl_t ipl; 458 call_t *call; 459 460 call = notify_box ? ipc_call_alloc(0) : NULL; 461 462 /* Disconnect all phones connected to our answerbox */ 463 restart_phones: 464 ipl = interrupts_disable(); 465 spinlock_lock(&box->lock); 466 while (!list_empty(&box->connected_phones)) { 467 phone = list_get_instance(box->connected_phones.next, 468 phone_t, link); 469 if (SYNCH_FAILED(mutex_trylock(&phone->lock))) { 470 spinlock_unlock(&box->lock); 471 interrupts_restore(ipl); 472 DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD); 473 goto restart_phones; 474 } 475 476 /* Disconnect phone */ 477 ASSERT(phone->state == IPC_PHONE_CONNECTED); 478 479 list_remove(&phone->link); 480 phone->state = IPC_PHONE_SLAMMED; 481 482 if (notify_box) { 483 mutex_unlock(&phone->lock); 484 spinlock_unlock(&box->lock); 485 interrupts_restore(ipl); 486 487 /* 488 * Send one message to the answerbox for each 489 * phone. Used to make sure the kbox thread 490 * wakes up after the last phone has been 491 * disconnected. 492 */ 493 IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP); 494 call->flags |= IPC_CALL_DISCARD_ANSWER; 495 _ipc_call(phone, box, call); 496 497 /* Allocate another call in advance */ 498 call = ipc_call_alloc(0); 499 500 /* Must start again */ 501 goto restart_phones; 502 } 503 504 mutex_unlock(&phone->lock); 505 } 506 507 spinlock_unlock(&box->lock); 508 interrupts_restore(ipl); 509 510 /* Free unused call */ 511 if (call) ipc_call_free(call); 512 } 513 445 514 /** Cleans up all IPC communication of the current task. 446 515 * … … 452 521 int i; 453 522 call_t *call; 454 phone_t *phone;455 DEADLOCK_PROBE_INIT(p_phonelck);456 523 457 524 /* Disconnect all our phones ('ipc_phone_hangup') */ … … 462 529 ipc_irq_cleanup(&TASK->answerbox); 463 530 464 /* Disconnect all phones connected to our answerbox */ 465 restart_phones: 531 /* Disconnect all phones connected to our regular answerbox */ 532 ipc_answerbox_slam_phones(&TASK->answerbox, false); 533 534 #ifdef CONFIG_UDEBUG 535 /* Clean up kbox thread and communications */ 536 ipc_kbox_cleanup(); 537 #endif 538 539 /* Answer all messages in 'calls' and 'dispatched_calls' queues */ 466 540 spinlock_lock(&TASK->answerbox.lock); 467 while (!list_empty(&TASK->answerbox.connected_phones)) {468 phone = list_get_instance(TASK->answerbox.connected_phones.next,469 phone_t, link);470 if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {471 spinlock_unlock(&TASK->answerbox.lock);472 DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);473 goto restart_phones;474 }475 476 /* Disconnect phone */477 ASSERT(phone->state == IPC_PHONE_CONNECTED);478 phone->state = IPC_PHONE_SLAMMED;479 list_remove(&phone->link);480 481 mutex_unlock(&phone->lock);482 }483 484 /* Answer all messages in 'calls' and 'dispatched_calls' queues */485 541 ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls); 486 542 ipc_cleanup_call_list(&TASK->answerbox.calls); -
kernel/generic/src/ipc/sysipc.c
r06a195bc r9a1b20c 43 43 #include <ipc/irq.h> 44 44 #include <ipc/ipcrsc.h> 45 #include <ipc/ipc_kbox.h> 46 #include <udebug/udebug_ipc.h> 45 47 #include <arch/interrupt.h> 46 48 #include <print.h> … … 296 298 * 297 299 * @param call Call structure with the request. 300 * @param phone Phone that the call will be sent through. 298 301 * 299 302 * @return Return 0 on success, ELIMIT or EPERM on error. 300 303 */ 301 static int request_preprocess(call_t *call )304 static int request_preprocess(call_t *call, phone_t *phone) 302 305 { 303 306 int newphid; … … 341 344 } 342 345 break; 346 #ifdef CONFIG_UDEBUG 347 case IPC_M_DEBUG_ALL: 348 return udebug_request_preprocess(call, phone); 349 #endif 343 350 default: 344 351 break; … … 370 377 if (call->buffer) { 371 378 /* This must be an affirmative answer to IPC_M_DATA_READ. */ 379 /* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */ 372 380 uintptr_t dst = IPC_GET_ARG1(call->data); 373 381 size_t size = IPC_GET_ARG2(call->data); … … 400 408 } 401 409 IPC_SET_ARG5(call->data, phoneid); 402 } 410 } 411 switch (IPC_GET_METHOD(call->data)) { 412 case IPC_M_DEBUG_ALL: 413 return -1; 414 default: 415 break; 416 } 403 417 return 0; 404 418 } … … 442 456 IPC_SET_ARG5(call.data, 0); 443 457 444 if (!(res = request_preprocess(&call ))) {458 if (!(res = request_preprocess(&call, phone))) { 445 459 rc = ipc_call_sync(phone, &call); 446 460 if (rc != EOK) … … 482 496 GET_CHECK_PHONE(phone, phoneid, return ENOENT); 483 497 484 if (!(res = request_preprocess(&call ))) {498 if (!(res = request_preprocess(&call, phone))) { 485 499 rc = ipc_call_sync(phone, &call); 486 500 if (rc != EOK) … … 551 565 IPC_SET_ARG5(call->data, 0); 552 566 553 if (!(res = request_preprocess(call )))567 if (!(res = request_preprocess(call, phone))) 554 568 ipc_call(phone, call); 555 569 else … … 585 599 return (unative_t) rc; 586 600 } 587 if (!(res = request_preprocess(call )))601 if (!(res = request_preprocess(call, phone))) 588 602 ipc_call(phone, call); 589 603 else … … 869 883 } 870 884 885 #include <console/console.h> 886 887 /** 888 * Syscall connect to a task by id. 889 * 890 * @return Phone id on success, or negative error code. 891 */ 892 unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg) 893 { 894 #ifdef CONFIG_UDEBUG 895 sysarg64_t taskid_arg; 896 int rc; 897 898 rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t)); 899 if (rc != 0) 900 return (unative_t) rc; 901 902 printf("sys_ipc_connect_kbox(%lld, %d)\n", taskid_arg.value); 903 904 return ipc_connect_kbox(taskid_arg.value); 905 #else 906 return (unative_t) ENOTSUP; 907 #endif 908 } 909 871 910 /** @} 872 911 */
Note:
See TracChangeset
for help on using the changeset viewer.