Changes in kernel/generic/src/ipc/sysipc.c [6c34f587:4e5dabf] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/sysipc.c
r6c34f587 r4e5dabf 612 612 break; 613 613 } 614 615 return 0; 616 } 617 618 /** Make a fast call over IPC, wait for reply and return to user. 619 * 620 * This function can handle only three arguments of payload, but is faster than 621 * the generic function (i.e. sys_ipc_call_sync_slow()). 622 * 623 * @param phoneid Phone handle for the call. 624 * @param imethod Interface and method of the call. 625 * @param arg1 Service-defined payload argument. 626 * @param arg2 Service-defined payload argument. 627 * @param arg3 Service-defined payload argument. 628 * @param data Address of user-space structure where the reply call will 629 * be stored. 630 * 631 * @return 0 on success. 632 * @return ENOENT if there is no such phone handle. 633 * 634 */ 635 sysarg_t sys_ipc_call_sync_fast(sysarg_t phoneid, sysarg_t imethod, 636 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_data_t *data) 637 { 638 phone_t *phone; 639 if (phone_get(phoneid, &phone) != EOK) 640 return ENOENT; 641 642 call_t *call = ipc_call_alloc(0); 643 IPC_SET_IMETHOD(call->data, imethod); 644 IPC_SET_ARG1(call->data, arg1); 645 IPC_SET_ARG2(call->data, arg2); 646 IPC_SET_ARG3(call->data, arg3); 647 648 /* 649 * To achieve deterministic behavior, zero out arguments that are beyond 650 * the limits of the fast version. 651 */ 652 IPC_SET_ARG4(call->data, 0); 653 IPC_SET_ARG5(call->data, 0); 654 655 int res = request_preprocess(call, phone); 656 int rc; 657 658 if (!res) { 659 #ifdef CONFIG_UDEBUG 660 udebug_stoppable_begin(); 661 #endif 662 rc = ipc_call_sync(phone, call); 663 #ifdef CONFIG_UDEBUG 664 udebug_stoppable_end(); 665 #endif 666 667 if (rc != EOK) { 668 /* The call will be freed by ipc_cleanup(). */ 669 return rc; 670 } 671 672 process_answer(call); 673 } else 674 IPC_SET_RETVAL(call->data, res); 675 676 rc = STRUCT_TO_USPACE(&data->args, &call->data.args); 677 ipc_call_free(call); 678 if (rc != 0) 679 return rc; 680 681 return 0; 682 } 683 684 /** Make a synchronous IPC call allowing to transmit the entire payload. 685 * 686 * @param phoneid Phone handle for the call. 687 * @param request User-space address of call data with the request. 688 * @param reply User-space address of call data where to store the 689 * answer. 690 * 691 * @return Zero on success or an error code. 692 * 693 */ 694 sysarg_t sys_ipc_call_sync_slow(sysarg_t phoneid, ipc_data_t *request, 695 ipc_data_t *reply) 696 { 697 phone_t *phone; 698 if (phone_get(phoneid, &phone) != EOK) 699 return ENOENT; 700 701 call_t *call = ipc_call_alloc(0); 702 int rc = copy_from_uspace(&call->data.args, &request->args, 703 sizeof(call->data.args)); 704 if (rc != 0) { 705 ipc_call_free(call); 706 return (sysarg_t) rc; 707 } 708 709 int res = request_preprocess(call, phone); 710 711 if (!res) { 712 #ifdef CONFIG_UDEBUG 713 udebug_stoppable_begin(); 714 #endif 715 rc = ipc_call_sync(phone, call); 716 #ifdef CONFIG_UDEBUG 717 udebug_stoppable_end(); 718 #endif 719 720 if (rc != EOK) { 721 /* The call will be freed by ipc_cleanup(). */ 722 return rc; 723 } 724 725 process_answer(call); 726 } else 727 IPC_SET_RETVAL(call->data, res); 728 729 rc = STRUCT_TO_USPACE(&reply->args, &call->data.args); 730 ipc_call_free(call); 731 if (rc != 0) 732 return rc; 614 733 615 734 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.