Changes in / [14c5005:45cbcaf4] in mainline
- Files:
-
- 34 deleted
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r14c5005 r45cbcaf4 89 89 @ "tmpfs" TMPFS image 90 90 @ "fat" FAT16 image 91 @ "ext 4fs" ext4image91 @ "ext2fs" EXT2 image 92 92 ! RDFMT (choice) 93 93 -
abi/include/syscall.h
r14c5005 r45cbcaf4 63 63 SYS_PAGE_FIND_MAPPING, 64 64 65 SYS_IPC_CALL_SYNC_FAST, 66 SYS_IPC_CALL_SYNC_SLOW, 65 67 SYS_IPC_CALL_ASYNC_FAST, 66 68 SYS_IPC_CALL_ASYNC_SLOW, -
boot/Makefile
r14c5005 r45cbcaf4 47 47 $(MKFAT) 1048576 $(DIST_PATH) $@ 48 48 endif 49 ifeq ($(RDFMT),ext 4fs)50 $(MKEXT 4) 1048576 $(DIST_PATH) $@49 ifeq ($(RDFMT),ext2fs) 50 $(MKEXT2) 1048576 $(DIST_PATH) $@ 51 51 endif 52 52 -
boot/Makefile.common
r14c5005 r45cbcaf4 55 55 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py 56 56 MKFAT = $(TOOLS_PATH)/mkfat.py 57 MKEXT 4 = $(TOOLS_PATH)/mkext4.py57 MKEXT2 = $(TOOLS_PATH)/mkext2.py 58 58 MKUIMAGE = $(TOOLS_PATH)/mkuimage.py 59 59 … … 84 84 endif 85 85 86 ifeq ($(RDFMT),ext 4fs)87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext 4fs/ext4fs86 ifeq ($(RDFMT),ext2fs) 87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext2fs/ext2fs 88 88 endif 89 89 … … 106 106 $(USPACE_PATH)/srv/fs/exfat/exfat \ 107 107 $(USPACE_PATH)/srv/fs/ext2fs/ext2fs \ 108 $(USPACE_PATH)/srv/fs/ext4fs/ext4fs \109 108 $(USPACE_PATH)/srv/hid/remcons/remcons \ 110 109 $(USPACE_PATH)/srv/net/ethip/ethip \ … … 174 173 $(USPACE_PATH)/app/tester/tester \ 175 174 $(USPACE_PATH)/app/testread/testread \ 176 $(USPACE_PATH)/app/testwrit/testwrit \177 175 $(USPACE_PATH)/app/tetris/tetris \ 178 176 $(USPACE_PATH)/app/trace/trace \ -
kernel/generic/include/ipc/ipc.h
r14c5005 r45cbcaf4 77 77 waitq_t wq; 78 78 79 /** Linkage for the list of task's synchronous answerboxes. */ 80 link_t sync_box_link; 81 79 82 /** Phones connected to this answerbox. */ 80 83 list_t connected_phones; … … 113 116 struct task *sender; 114 117 118 /* 119 * The caller box is different from sender->answerbox 120 * for synchronous calls. 121 */ 122 answerbox_t *callerbox; 123 115 124 /** Private data to internal IPC. */ 116 125 sysarg_t priv; … … 138 147 139 148 extern int ipc_call(phone_t *, call_t *); 149 extern int ipc_call_sync(phone_t *, call_t *); 140 150 extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int); 141 151 extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int); -
kernel/generic/include/ipc/sysipc.h
r14c5005 r45cbcaf4 40 40 #include <typedefs.h> 41 41 42 extern sysarg_t sys_ipc_call_sync_fast(sysarg_t, sysarg_t, sysarg_t, 43 sysarg_t, sysarg_t, ipc_data_t *); 44 extern sysarg_t sys_ipc_call_sync_slow(sysarg_t, ipc_data_t *, ipc_data_t *); 42 45 extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t, 43 46 sysarg_t, sysarg_t, sysarg_t); -
kernel/generic/include/proc/task.h
r14c5005 r45cbcaf4 94 94 phone_t phones[IPC_MAX_PHONES]; 95 95 stats_ipc_t ipc_info; /**< IPC statistics */ 96 list_t sync_boxes; /**< List of synchronous answerboxes. */ 96 97 event_t events[EVENT_TASK_END - EVENT_END]; 97 98 -
kernel/generic/src/ipc/ipc.c
r14c5005 r45cbcaf4 71 71 { 72 72 memsetb(call, sizeof(*call), 0); 73 call->callerbox = &TASK->answerbox; 73 74 call->sender = TASK; 74 75 call->buffer = NULL; … … 119 120 irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock"); 120 121 waitq_initialize(&box->wq); 122 link_initialize(&box->sync_box_link); 121 123 list_initialize(&box->connected_phones); 122 124 list_initialize(&box->calls); … … 161 163 } 162 164 165 /** Helper function to facilitate synchronous calls. 166 * 167 * @param phone Destination kernel phone structure. 168 * @param request Call structure with request. 169 * 170 * @return EOK on success or EINTR if the sleep was interrupted. 171 * 172 */ 173 int ipc_call_sync(phone_t *phone, call_t *request) 174 { 175 answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0); 176 ipc_answerbox_init(sync_box, TASK); 177 178 /* 179 * Put the answerbox on the TASK's list of synchronous answerboxes so 180 * that it can be cleaned up if the call is interrupted. 181 */ 182 irq_spinlock_lock(&TASK->lock, true); 183 list_append(&sync_box->sync_box_link, &TASK->sync_boxes); 184 irq_spinlock_unlock(&TASK->lock, true); 185 186 /* We will receive data in a special box. */ 187 request->callerbox = sync_box; 188 189 ipc_call(phone, request); 190 if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT, 191 SYNCH_FLAGS_INTERRUPTIBLE)) { 192 /* The answerbox and the call will be freed by ipc_cleanup(). */ 193 return EINTR; 194 } 195 196 /* 197 * The answer arrived without interruption so we can remove the 198 * answerbox from the TASK's list of synchronous answerboxes. 199 */ 200 irq_spinlock_lock(&TASK->lock, true); 201 list_remove(&sync_box->sync_box_link); 202 irq_spinlock_unlock(&TASK->lock, true); 203 204 slab_free(ipc_answerbox_slab, sync_box); 205 return EOK; 206 } 207 163 208 /** Answer a message which was not dispatched and is not listed in any queue. 164 209 * … … 169 214 static void _ipc_answer_free_call(call_t *call, bool selflocked) 170 215 { 171 answerbox_t *callerbox = &call->sender->answerbox;216 answerbox_t *callerbox = call->callerbox; 172 217 bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox)); 173 218 … … 561 606 ipc_cleanup_call_list(&TASK->answerbox.calls); 562 607 irq_spinlock_unlock(&TASK->answerbox.lock, true); 608 609 /* Wait for all answers to interrupted synchronous calls to arrive */ 610 ipl_t ipl = interrupts_disable(); 611 while (!list_empty(&TASK->sync_boxes)) { 612 answerbox_t *box = list_get_instance( 613 list_first(&TASK->sync_boxes), answerbox_t, sync_box_link); 614 615 list_remove(&box->sync_box_link); 616 call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT, 617 SYNCH_FLAGS_NONE); 618 ipc_call_free(call); 619 slab_free(ipc_answerbox_slab, box); 620 } 621 interrupts_restore(ipl); 563 622 564 623 /* Wait for all answers to asynchronous calls to arrive */ -
kernel/generic/src/ipc/sysipc.c
r14c5005 r45cbcaf4 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; -
kernel/generic/src/proc/task.c
r14c5005 r45cbcaf4 156 156 157 157 list_initialize(&task->threads); 158 list_initialize(&task->sync_boxes); 158 159 159 160 ipc_answerbox_init(&task->answerbox, task); -
kernel/generic/src/syscall/syscall.c
r14c5005 r45cbcaf4 151 151 152 152 /* IPC related syscalls. */ 153 (syshandler_t) sys_ipc_call_sync_fast, 154 (syshandler_t) sys_ipc_call_sync_slow, 153 155 (syshandler_t) sys_ipc_call_async_fast, 154 156 (syshandler_t) sys_ipc_call_async_slow, -
uspace/Makefile
r14c5005 r45cbcaf4 58 58 app/tester \ 59 59 app/testread \ 60 app/testwrit \61 60 app/tetris \ 62 61 app/trace \ … … 99 98 srv/fs/locfs \ 100 99 srv/fs/ext2fs \ 101 srv/fs/ext4fs \102 100 srv/hid/console \ 103 101 srv/hid/s3c24xx_ts \ … … 201 199 lib/nic \ 202 200 lib/ext2 \ 203 lib/ext4 \204 201 lib/usb \ 205 202 lib/usbhost \ -
uspace/Makefile.common
r14c5005 r45cbcaf4 115 115 116 116 LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2 117 LIBEXT4_PREFIX = $(LIB_PREFIX)/ext4118 117 119 118 LIBUSB_PREFIX = $(LIB_PREFIX)/usb -
uspace/app/trace/syscalls.c
r14c5005 r45cbcaf4 53 53 [SYS_AS_AREA_DESTROY] = { "as_area_destroy", 1, V_ERRNO }, 54 54 55 [SYS_IPC_CALL_SYNC_FAST] = { "ipc_call_sync_fast", 6, V_ERRNO }, 56 [SYS_IPC_CALL_SYNC_SLOW] = { "ipc_call_sync_slow", 3, V_ERRNO }, 55 57 [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, V_HASH }, 56 58 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, V_HASH }, -
uspace/app/trace/trace.c
r14c5005 r45cbcaf4 318 318 } 319 319 320 static void sc_ipc_call_sync_fast(sysarg_t *sc_args) 321 { 322 ipc_call_t question, reply; 323 int rc; 324 int phoneid; 325 326 phoneid = sc_args[0]; 327 328 IPC_SET_IMETHOD(question, sc_args[1]); 329 IPC_SET_ARG1(question, sc_args[2]); 330 IPC_SET_ARG2(question, sc_args[3]); 331 IPC_SET_ARG3(question, sc_args[4]); 332 IPC_SET_ARG4(question, 0); 333 IPC_SET_ARG5(question, 0); 334 335 memset(&reply, 0, sizeof(reply)); 336 rc = udebug_mem_read(sess, &reply.args, sc_args[5], sizeof(reply.args)); 337 if (rc < 0) 338 return; 339 340 ipcp_call_sync(phoneid, &question, &reply); 341 } 342 343 static void sc_ipc_call_sync_slow_b(unsigned thread_id, sysarg_t *sc_args) 344 { 345 ipc_call_t question; 346 int rc; 347 348 memset(&question, 0, sizeof(question)); 349 rc = udebug_mem_read(sess, &question.args, sc_args[1], 350 sizeof(question.args)); 351 352 if (rc < 0) { 353 printf("Error: mem_read->%d\n", rc); 354 return; 355 } 356 357 thread_ipc_req[thread_id] = question; 358 } 359 360 static void sc_ipc_call_sync_slow_e(unsigned thread_id, sysarg_t *sc_args) 361 { 362 ipc_call_t reply; 363 int rc; 364 365 memset(&reply, 0, sizeof(reply)); 366 rc = udebug_mem_read(sess, &reply.args, sc_args[2], 367 sizeof(reply.args)); 368 369 if (rc < 0) { 370 printf("Error: mem_read->%d\n", rc); 371 return; 372 } 373 374 ipcp_call_sync(sc_args[0], &thread_ipc_req[thread_id], &reply); 375 } 376 320 377 static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc) 321 378 { … … 351 408 print_sc_args(sc_args, syscall_desc[sc_id].n_args); 352 409 } 410 411 switch (sc_id) { 412 case SYS_IPC_CALL_SYNC_SLOW: 413 sc_ipc_call_sync_slow_b(thread_id, sc_args); 414 break; 415 default: 416 break; 417 } 353 418 } 354 419 … … 382 447 case SYS_IPC_CALL_ASYNC_SLOW: 383 448 sc_ipc_call_async_slow(sc_args, sc_rc); 449 break; 450 case SYS_IPC_CALL_SYNC_FAST: 451 sc_ipc_call_sync_fast(sc_args); 452 break; 453 case SYS_IPC_CALL_SYNC_SLOW: 454 sc_ipc_call_sync_slow_e(thread_id, sc_args); 384 455 break; 385 456 case SYS_IPC_WAIT: -
uspace/lib/c/generic/async.c
r14c5005 r45cbcaf4 114 114 #include <stdlib.h> 115 115 #include <macros.h> 116 #include "private/libc.h"117 116 118 117 #define CLIENT_HASH_TABLE_BUCKETS 32 … … 2167 2166 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 2168 2167 { 2169 return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags, 2170 (sysarg_t) __entry); 2168 return ipc_share_in_finalize(callid, src, flags); 2171 2169 } 2172 2170 … … 2235 2233 int async_share_out_finalize(ipc_callid_t callid, void **dst) 2236 2234 { 2237 return ipc_ answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t)dst);2235 return ipc_share_out_finalize(callid, dst); 2238 2236 } 2239 2237 … … 2319 2317 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 2320 2318 { 2321 return ipc_ answer_2(callid, EOK, (sysarg_t) src, (sysarg_t)size);2319 return ipc_data_read_finalize(callid, src, size); 2322 2320 } 2323 2321 … … 2422 2420 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 2423 2421 { 2424 return ipc_ answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t)size);2422 return ipc_data_write_finalize(callid, dst, size); 2425 2423 } 2426 2424 -
uspace/lib/c/generic/ipc.c
r14c5005 r45cbcaf4 48 48 #include <fibril.h> 49 49 #include <macros.h> 50 #include "private/libc.h" 50 51 51 52 /** … … 82 83 83 84 static atomic_t ipc_futex = FUTEX_INITIALIZER; 85 86 /** Fast synchronous call. 87 * 88 * Only three payload arguments can be passed using this function. However, 89 * this function is faster than the generic ipc_call_sync_slow() because 90 * the payload is passed directly in registers. 91 * 92 * @param phoneid Phone handle for the call. 93 * @param method Requested method. 94 * @param arg1 Service-defined payload argument. 95 * @param arg2 Service-defined payload argument. 96 * @param arg3 Service-defined payload argument. 97 * @param result1 If non-NULL, the return ARG1 will be stored there. 98 * @param result2 If non-NULL, the return ARG2 will be stored there. 99 * @param result3 If non-NULL, the return ARG3 will be stored there. 100 * @param result4 If non-NULL, the return ARG4 will be stored there. 101 * @param result5 If non-NULL, the return ARG5 will be stored there. 102 * 103 * @return Negative values representing IPC errors. 104 * @return Otherwise the RETVAL of the answer. 105 * 106 */ 107 int ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1, 108 sysarg_t arg2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2, 109 sysarg_t *result3, sysarg_t *result4, sysarg_t *result5) 110 { 111 ipc_call_t resdata; 112 int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1, 113 arg2, arg3, (sysarg_t) &resdata); 114 if (callres) 115 return callres; 116 117 if (result1) 118 *result1 = IPC_GET_ARG1(resdata); 119 if (result2) 120 *result2 = IPC_GET_ARG2(resdata); 121 if (result3) 122 *result3 = IPC_GET_ARG3(resdata); 123 if (result4) 124 *result4 = IPC_GET_ARG4(resdata); 125 if (result5) 126 *result5 = IPC_GET_ARG5(resdata); 127 128 return IPC_GET_RETVAL(resdata); 129 } 130 131 /** Synchronous call transmitting 5 arguments of payload. 132 * 133 * @param phoneid Phone handle for the call. 134 * @param imethod Requested interface and method. 135 * @param arg1 Service-defined payload argument. 136 * @param arg2 Service-defined payload argument. 137 * @param arg3 Service-defined payload argument. 138 * @param arg4 Service-defined payload argument. 139 * @param arg5 Service-defined payload argument. 140 * @param result1 If non-NULL, storage for the first return argument. 141 * @param result2 If non-NULL, storage for the second return argument. 142 * @param result3 If non-NULL, storage for the third return argument. 143 * @param result4 If non-NULL, storage for the fourth return argument. 144 * @param result5 If non-NULL, storage for the fifth return argument. 145 * 146 * @return Negative values representing IPC errors. 147 * @return Otherwise the RETVAL of the answer. 148 * 149 */ 150 int ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1, 151 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 152 sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, sysarg_t *result4, 153 sysarg_t *result5) 154 { 155 ipc_call_t data; 156 157 IPC_SET_IMETHOD(data, imethod); 158 IPC_SET_ARG1(data, arg1); 159 IPC_SET_ARG2(data, arg2); 160 IPC_SET_ARG3(data, arg3); 161 IPC_SET_ARG4(data, arg4); 162 IPC_SET_ARG5(data, arg5); 163 164 int callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid, 165 (sysarg_t) &data, (sysarg_t) &data); 166 if (callres) 167 return callres; 168 169 if (result1) 170 *result1 = IPC_GET_ARG1(data); 171 if (result2) 172 *result2 = IPC_GET_ARG2(data); 173 if (result3) 174 *result3 = IPC_GET_ARG3(data); 175 if (result4) 176 *result4 = IPC_GET_ARG4(data); 177 if (result5) 178 *result5 = IPC_GET_ARG5(data); 179 180 return IPC_GET_RETVAL(data); 181 } 84 182 85 183 /** Send asynchronous message via syscall. … … 513 611 } 514 612 613 /** Request callback connection. 614 * 615 * The @a task_id and @a phonehash identifiers returned 616 * by the kernel can be used for connection tracking. 617 * 618 * @param phoneid Phone handle used for contacting the other side. 619 * @param arg1 User defined argument. 620 * @param arg2 User defined argument. 621 * @param arg3 User defined argument. 622 * @param task_id Identifier of the client task. 623 * @param phonehash Opaque identifier of the phone that will 624 * be used for incoming calls. 625 * 626 * @return Zero on success or a negative error code. 627 * 628 */ 629 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 630 task_id_t *task_id, sysarg_t *phonehash) 631 { 632 ipc_call_t data; 633 int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, 634 IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data); 635 if (rc == EOK) { 636 *task_id = data.in_task_id; 637 *phonehash = IPC_GET_ARG5(data); 638 } 639 return rc; 640 } 641 642 /** Request cloned connection. 643 * 644 * @param phoneid Phone handle used for contacting the other side. 645 * 646 * @return Cloned phone handle on success or a negative error code. 647 * 648 */ 649 int ipc_clone_establish(int phoneid) 650 { 651 sysarg_t newphid; 652 int res = ipc_call_sync_0_5(phoneid, IPC_M_CLONE_ESTABLISH, NULL, 653 NULL, NULL, NULL, &newphid); 654 if (res) 655 return res; 656 657 return newphid; 658 } 659 660 /** Request new connection. 661 * 662 * @param phoneid Phone handle used for contacting the other side. 663 * @param arg1 User defined argument. 664 * @param arg2 User defined argument. 665 * @param arg3 User defined argument. 666 * 667 * @return New phone handle on success or a negative error code. 668 * 669 */ 670 int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) 671 { 672 sysarg_t newphid; 673 int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 674 NULL, NULL, NULL, NULL, &newphid); 675 if (res) 676 return res; 677 678 return newphid; 679 } 680 681 /** Request new connection (blocking) 682 * 683 * If the connection is not available at the moment, the 684 * call should block. This has to be, however, implemented 685 * on the server side. 686 * 687 * @param phoneid Phone handle used for contacting the other side. 688 * @param arg1 User defined argument. 689 * @param arg2 User defined argument. 690 * @param arg3 User defined argument. 691 * 692 * @return New phone handle on success or a negative error code. 693 * 694 */ 695 int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2, 696 sysarg_t arg3) 697 { 698 sysarg_t newphid; 699 int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 700 IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid); 701 if (res) 702 return res; 703 704 return newphid; 705 } 706 515 707 /** Hang up a phone. 516 708 * … … 566 758 } 567 759 760 /** Wrapper for IPC_M_SHARE_IN calls. 761 * 762 * @param phoneid Phone that will be used to contact the receiving side. 763 * @param size Size of the destination address space area. 764 * @param arg User defined argument. 765 * @param flags Storage for received flags. Can be NULL. 766 * @param dst Destination address space area base. Cannot be NULL. 767 * 768 * @return Zero on success or a negative error code from errno.h. 769 * 770 */ 771 int ipc_share_in_start(int phoneid, size_t size, sysarg_t arg, 772 unsigned int *flags, void **dst) 773 { 774 sysarg_t _flags = 0; 775 sysarg_t _dst = (sysarg_t) -1; 776 int res = ipc_call_sync_2_4(phoneid, IPC_M_SHARE_IN, (sysarg_t) size, 777 arg, NULL, &_flags, NULL, &_dst); 778 779 if (flags) 780 *flags = (unsigned int) _flags; 781 782 *dst = (void *) _dst; 783 return res; 784 } 785 786 /** Wrapper for answering the IPC_M_SHARE_IN calls. 787 * 788 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_IN 789 * calls so that the user doesn't have to remember the meaning of each 790 * IPC argument. 791 * 792 * @param callid Hash of the IPC_M_DATA_READ call to answer. 793 * @param src Source address space base. 794 * @param flags Flags to be used for sharing. Bits can be only cleared. 795 * 796 * @return Zero on success or a value from @ref errno.h on failure. 797 * 798 */ 799 int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 800 { 801 return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags, 802 (sysarg_t) __entry); 803 } 804 805 /** Wrapper for IPC_M_SHARE_OUT calls. 806 * 807 * @param phoneid Phone that will be used to contact the receiving side. 808 * @param src Source address space area base address. 809 * @param flags Flags to be used for sharing. Bits can be only cleared. 810 * 811 * @return Zero on success or a negative error code from errno.h. 812 * 813 */ 814 int ipc_share_out_start(int phoneid, void *src, unsigned int flags) 815 { 816 return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0, 817 (sysarg_t) flags); 818 } 819 820 /** Wrapper for answering the IPC_M_SHARE_OUT calls. 821 * 822 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT 823 * calls so that the user doesn't have to remember the meaning of each 824 * IPC argument. 825 * 826 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 827 * @param dst Destination address space area base address. 828 * 829 * @return Zero on success or a value from @ref errno.h on failure. 830 * 831 */ 832 int ipc_share_out_finalize(ipc_callid_t callid, void **dst) 833 { 834 return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst); 835 } 836 837 /** Wrapper for IPC_M_DATA_READ calls. 838 * 839 * @param phoneid Phone that will be used to contact the receiving side. 840 * @param dst Address of the beginning of the destination buffer. 841 * @param size Size of the destination buffer. 842 * 843 * @return Zero on success or a negative error code from errno.h. 844 * 845 */ 846 int ipc_data_read_start(int phoneid, void *dst, size_t size) 847 { 848 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst, 849 (sysarg_t) size); 850 } 851 852 /** Wrapper for answering the IPC_M_DATA_READ calls. 853 * 854 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ 855 * calls so that the user doesn't have to remember the meaning of each 856 * IPC argument. 857 * 858 * @param callid Hash of the IPC_M_DATA_READ call to answer. 859 * @param src Source address for the IPC_M_DATA_READ call. 860 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 861 * the maximum size announced by the sender. 862 * 863 * @return Zero on success or a value from @ref errno.h on failure. 864 * 865 */ 866 int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 867 { 868 return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size); 869 } 870 871 /** Wrapper for IPC_M_DATA_WRITE calls. 872 * 873 * @param phoneid Phone that will be used to contact the receiving side. 874 * @param src Address of the beginning of the source buffer. 875 * @param size Size of the source buffer. 876 * 877 * @return Zero on success or a negative error code from errno.h. 878 * 879 */ 880 int ipc_data_write_start(int phoneid, const void *src, size_t size) 881 { 882 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src, 883 (sysarg_t) size); 884 } 885 886 /** Wrapper for answering the IPC_M_DATA_WRITE calls. 887 * 888 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE 889 * calls so that the user doesn't have to remember the meaning of each 890 * IPC argument. 891 * 892 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 893 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 894 * @param size Final size for the IPC_M_DATA_WRITE call. 895 * 896 * @return Zero on success or a value from @ref errno.h on failure. 897 * 898 */ 899 int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 900 { 901 return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size); 902 } 903 568 904 /** Connect to a task specified by id. 569 905 * -
uspace/lib/c/include/ipc/ipc.h
r14c5005 r45cbcaf4 48 48 typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *); 49 49 50 /* 51 * User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow(). 52 * They are in the form ipc_call_sync_m_n(), where m denotes the number of 53 * arguments of payload and n denotes number of return values. Whenever 54 * possible, the fast version is used. 55 */ 56 57 #define ipc_call_sync_0_0(phoneid, method) \ 58 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0) 59 #define ipc_call_sync_0_1(phoneid, method, res1) \ 60 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0) 61 #define ipc_call_sync_0_2(phoneid, method, res1, res2) \ 62 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0) 63 #define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \ 64 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ 65 0, 0) 66 #define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \ 67 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ 68 (res4), 0) 69 #define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \ 70 ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \ 71 (res4), (res5)) 72 73 #define ipc_call_sync_1_0(phoneid, method, arg1) \ 74 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0) 75 #define ipc_call_sync_1_1(phoneid, method, arg1, res1) \ 76 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0) 77 #define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \ 78 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \ 79 0, 0) 80 #define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \ 81 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ 82 (res3), 0, 0) 83 #define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \ 84 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ 85 (res3), (res4), 0) 86 #define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \ 87 res5) \ 88 ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \ 89 (res3), (res4), (res5)) 90 91 #define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \ 92 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \ 93 0, 0) 94 #define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \ 95 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \ 96 0, 0) 97 #define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \ 98 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ 99 (res2), 0, 0, 0) 100 #define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \ 101 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ 102 (res2), (res3), 0, 0) 103 #define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \ 104 res4) \ 105 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ 106 (res2), (res3), (res4), 0) 107 #define ipc_call_sync_2_5(phoneid, method, arg1, arg2, res1, res2, res3, \ 108 res4, res5)\ 109 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \ 110 (res2), (res3), (res4), (res5)) 111 112 #define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \ 113 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \ 114 0, 0) 115 #define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \ 116 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \ 117 0, 0, 0, 0) 118 #define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \ 119 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \ 120 (res2), 0, 0, 0) 121 #define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \ 122 res3) \ 123 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 124 (res1), (res2), (res3), 0, 0) 125 #define ipc_call_sync_3_4(phoneid, method, arg1, arg2, arg3, res1, res2, \ 126 res3, res4) \ 127 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 128 (res1), (res2), (res3), (res4), 0) 129 #define ipc_call_sync_3_5(phoneid, method, arg1, arg2, arg3, res1, res2, \ 130 res3, res4, res5) \ 131 ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 132 (res1), (res2), (res3), (res4), (res5)) 133 134 #define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \ 135 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ 136 0, 0, 0, 0, 0) 137 #define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \ 138 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ 139 (res1), 0, 0, 0, 0) 140 #define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \ 141 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \ 142 (res1), (res2), 0, 0, 0) 143 #define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \ 144 res3) \ 145 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 146 (arg4), 0, (res1), (res2), (res3), 0, 0) 147 #define ipc_call_sync_4_4(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \ 148 res3, res4) \ 149 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 150 (arg4), 0, (res1), (res2), (res3), (res4), 0) 151 #define ipc_call_sync_4_5(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \ 152 res3, res4, res5) \ 153 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 154 (arg4), 0, (res1), (res2), (res3), (res4), (res5)) 155 156 #define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \ 157 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ 158 (arg5), 0, 0, 0, 0, 0) 159 #define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \ 160 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ 161 (arg5), (res1), 0, 0, 0, 0) 162 #define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \ 163 res2) \ 164 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 165 (arg4), (arg5), (res1), (res2), 0, 0, 0) 166 #define ipc_call_sync_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \ 167 res2, res3) \ 168 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 169 (arg4), (arg5), (res1), (res2), (res3), 0, 0) 170 #define ipc_call_sync_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \ 171 res2, res3, res4) \ 172 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 173 (arg4), (arg5), (res1), (res2), (res3), (res4), 0) 174 #define ipc_call_sync_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \ 175 res2, res3, res4, res5) \ 176 ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ 177 (arg4), (arg5), (res1), (res2), (res3), (res4), (res5)) 178 179 extern int ipc_call_sync_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 180 sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *); 181 182 extern int ipc_call_sync_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 183 sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, 184 sysarg_t *); 185 50 186 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int); 51 187 extern void ipc_poke(void); … … 118 254 sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool); 119 255 256 extern int ipc_clone_establish(int); 257 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *, 258 sysarg_t *); 259 extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t); 260 extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t); 261 120 262 extern int ipc_hangup(int); 121 263 … … 125 267 sysarg_t, sysarg_t, sysarg_t, unsigned int); 126 268 269 /* 270 * User-friendly wrappers for ipc_share_in_start(). 271 */ 272 273 #define ipc_share_in_start_0_0(phoneid, size, dst) \ 274 ipc_share_in_start((phoneid), (size), 0, NULL, (dst)) 275 #define ipc_share_in_start_0_1(phoneid, size, flags, dst) \ 276 ipc_share_in_start((phoneid), (size), 0, (flags), (dst)) 277 #define ipc_share_in_start_1_0(phoneid, size, arg, dst) \ 278 ipc_share_in_start((phoneid), (size), (arg), NULL, (dst)) 279 #define ipc_share_in_start_1_1(phoneid, size, arg, flags, dst) \ 280 ipc_share_in_start((phoneid), (size), (arg), (flags), (dst)) 281 282 extern int ipc_share_in_start(int, size_t, sysarg_t, unsigned int *, void **); 283 extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int); 284 extern int ipc_share_out_start(int, void *, unsigned int); 285 extern int ipc_share_out_finalize(ipc_callid_t, void **); 286 extern int ipc_data_read_start(int, void *, size_t); 287 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t); 288 extern int ipc_data_write_start(int, const void *, size_t); 289 extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t); 290 127 291 extern int ipc_connect_kbox(task_id_t); 128 292 -
uspace/srv/devman/devman.c
r14c5005 r45cbcaf4 1052 1052 } 1053 1053 1054 1054 1055 /** Find the device node structure of the device witch has the specified handle. 1055 1056 * … … 1141 1142 fun->state = FUN_INIT; 1142 1143 atomic_set(&fun->refcnt, 0); 1143 fibril_mutex_initialize(&fun->busy_lock);1144 1144 link_initialize(&fun->dev_functions); 1145 1145 list_initialize(&fun->match_ids.ids); … … 1184 1184 if (atomic_predec(&fun->refcnt) == 0) 1185 1185 delete_fun_node(fun); 1186 }1187 1188 /** Make function busy for reconfiguration operations. */1189 void fun_busy_lock(fun_node_t *fun)1190 {1191 fibril_mutex_lock(&fun->busy_lock);1192 }1193 1194 /** Mark end of reconfiguration operation. */1195 void fun_busy_unlock(fun_node_t *fun)1196 {1197 fibril_mutex_unlock(&fun->busy_lock);1198 1186 } 1199 1187 -
uspace/srv/devman/devman.h
r14c5005 r45cbcaf4 174 174 /** State */ 175 175 fun_state_t state; 176 /** Locked while performing reconfiguration operations */177 fibril_mutex_t busy_lock;178 176 179 177 /** The global unique identifier of the function */ … … 281 279 extern void dev_add_ref(dev_node_t *); 282 280 extern void dev_del_ref(dev_node_t *); 283 284 281 extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, 285 282 devman_handle_t handle); … … 293 290 extern void fun_add_ref(fun_node_t *); 294 291 extern void fun_del_ref(fun_node_t *); 295 extern void fun_busy_lock(fun_node_t *);296 extern void fun_busy_unlock(fun_node_t *);297 292 extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, 298 293 devman_handle_t handle); -
uspace/srv/devman/main.c
r14c5005 r45cbcaf4 432 432 433 433 fun_node_t *fun = create_fun_node(); 434 /* One reference for creation, one for us */435 fun_add_ref(fun);436 434 fun_add_ref(fun); 437 435 fun->ftype = ftype; 438 439 /*440 * We can lock the function here even when holding the tree because441 * we know it cannot be held by anyone else yet.442 */443 fun_busy_lock(fun);444 436 445 437 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 446 438 fibril_rwlock_write_unlock(&tree->rwlock); 447 439 dev_del_ref(pdev); 448 fun_busy_unlock(fun);449 fun_del_ref(fun);450 440 delete_fun_node(fun); 451 441 async_answer_0(callid, ENOMEM); … … 460 450 rc = online_function(fun); 461 451 if (rc != EOK) { 462 /* XXX Set some failed state? */ 463 fun_busy_unlock(fun); 464 fun_del_ref(fun); 452 /* XXX clean up */ 465 453 async_answer_0(callid, rc); 466 454 return; 467 455 } 468 469 fun_busy_unlock(fun);470 fun_del_ref(fun);471 456 472 457 /* Return device handle to parent's driver. */ … … 537 522 } 538 523 539 fun_busy_lock(fun);540 541 524 fibril_rwlock_read_lock(&device_tree.rwlock); 542 525 if (fun->dev == NULL || fun->dev->drv != drv) { 543 526 fibril_rwlock_read_unlock(&device_tree.rwlock); 544 fun_busy_unlock(fun);545 527 fun_del_ref(fun); 546 528 async_answer_0(iid, ENOENT); … … 551 533 rc = online_function(fun); 552 534 if (rc != EOK) { 553 fun_busy_unlock(fun);554 535 fun_del_ref(fun); 555 536 async_answer_0(iid, (sysarg_t) rc); … … 557 538 } 558 539 559 fun_busy_unlock(fun);560 540 fun_del_ref(fun); 561 541 … … 579 559 } 580 560 581 fun_busy_lock(fun);582 583 561 fibril_rwlock_write_lock(&device_tree.rwlock); 584 562 if (fun->dev == NULL || fun->dev->drv != drv) { 585 fun_busy_unlock(fun);586 563 fun_del_ref(fun); 587 564 async_answer_0(iid, ENOENT); … … 592 569 rc = offline_function(fun); 593 570 if (rc != EOK) { 594 fun_busy_unlock(fun);595 571 fun_del_ref(fun); 596 572 async_answer_0(iid, (sysarg_t) rc); … … 598 574 } 599 575 600 fun_busy_unlock(fun);601 576 fun_del_ref(fun); 602 577 async_answer_0(iid, (sysarg_t) EOK); … … 616 591 } 617 592 618 fun_busy_lock(fun);619 620 593 fibril_rwlock_write_lock(&tree->rwlock); 621 594 … … 625 598 if (fun->state == FUN_REMOVED) { 626 599 fibril_rwlock_write_unlock(&tree->rwlock); 627 fun_busy_unlock(fun);628 fun_del_ref(fun);629 600 async_answer_0(callid, ENOENT); 630 601 return; … … 667 638 if (gone_rc == EOK) 668 639 gone_rc = ENOTSUP; 669 fun_busy_unlock(fun);670 fun_del_ref(fun);671 640 async_answer_0(callid, gone_rc); 672 641 return; … … 695 664 "service."); 696 665 fibril_rwlock_write_unlock(&tree->rwlock); 697 fun_busy_unlock(fun);698 666 fun_del_ref(fun); 699 667 async_answer_0(callid, EIO); … … 705 673 remove_fun_node(&device_tree, fun); 706 674 fibril_rwlock_write_unlock(&tree->rwlock); 707 fun_busy_unlock(fun);708 675 709 676 /* Delete ref added when inserting function into tree */
Note:
See TracChangeset
for help on using the changeset viewer.