Changes in / [45cbcaf4:14c5005] in mainline
- Files:
-
- 34 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r45cbcaf4 r14c5005 89 89 @ "tmpfs" TMPFS image 90 90 @ "fat" FAT16 image 91 @ "ext 2fs" EXT2image91 @ "ext4fs" ext4 image 92 92 ! RDFMT (choice) 93 93 -
abi/include/syscall.h
r45cbcaf4 r14c5005 63 63 SYS_PAGE_FIND_MAPPING, 64 64 65 SYS_IPC_CALL_SYNC_FAST,66 SYS_IPC_CALL_SYNC_SLOW,67 65 SYS_IPC_CALL_ASYNC_FAST, 68 66 SYS_IPC_CALL_ASYNC_SLOW, -
boot/Makefile
r45cbcaf4 r14c5005 47 47 $(MKFAT) 1048576 $(DIST_PATH) $@ 48 48 endif 49 ifeq ($(RDFMT),ext 2fs)50 $(MKEXT 2) 1048576 $(DIST_PATH) $@49 ifeq ($(RDFMT),ext4fs) 50 $(MKEXT4) 1048576 $(DIST_PATH) $@ 51 51 endif 52 52 -
boot/Makefile.common
r45cbcaf4 r14c5005 55 55 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py 56 56 MKFAT = $(TOOLS_PATH)/mkfat.py 57 MKEXT 2 = $(TOOLS_PATH)/mkext2.py57 MKEXT4 = $(TOOLS_PATH)/mkext4.py 58 58 MKUIMAGE = $(TOOLS_PATH)/mkuimage.py 59 59 … … 84 84 endif 85 85 86 ifeq ($(RDFMT),ext 2fs)87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext 2fs/ext2fs86 ifeq ($(RDFMT),ext4fs) 87 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext4fs/ext4fs 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 \ 108 109 $(USPACE_PATH)/srv/hid/remcons/remcons \ 109 110 $(USPACE_PATH)/srv/net/ethip/ethip \ … … 173 174 $(USPACE_PATH)/app/tester/tester \ 174 175 $(USPACE_PATH)/app/testread/testread \ 176 $(USPACE_PATH)/app/testwrit/testwrit \ 175 177 $(USPACE_PATH)/app/tetris/tetris \ 176 178 $(USPACE_PATH)/app/trace/trace \ -
kernel/generic/include/ipc/ipc.h
r45cbcaf4 r14c5005 77 77 waitq_t wq; 78 78 79 /** Linkage for the list of task's synchronous answerboxes. */80 link_t sync_box_link;81 82 79 /** Phones connected to this answerbox. */ 83 80 list_t connected_phones; … … 116 113 struct task *sender; 117 114 118 /*119 * The caller box is different from sender->answerbox120 * for synchronous calls.121 */122 answerbox_t *callerbox;123 124 115 /** Private data to internal IPC. */ 125 116 sysarg_t priv; … … 147 138 148 139 extern int ipc_call(phone_t *, call_t *); 149 extern int ipc_call_sync(phone_t *, call_t *);150 140 extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int); 151 141 extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int); -
kernel/generic/include/ipc/sysipc.h
r45cbcaf4 r14c5005 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 *);45 42 extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t, 46 43 sysarg_t, sysarg_t, sysarg_t); -
kernel/generic/include/proc/task.h
r45cbcaf4 r14c5005 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. */97 96 event_t events[EVENT_TASK_END - EVENT_END]; 98 97 -
kernel/generic/src/ipc/ipc.c
r45cbcaf4 r14c5005 71 71 { 72 72 memsetb(call, sizeof(*call), 0); 73 call->callerbox = &TASK->answerbox;74 73 call->sender = TASK; 75 74 call->buffer = NULL; … … 120 119 irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock"); 121 120 waitq_initialize(&box->wq); 122 link_initialize(&box->sync_box_link);123 121 list_initialize(&box->connected_phones); 124 122 list_initialize(&box->calls); … … 163 161 } 164 162 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 so180 * 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 the198 * 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 208 163 /** Answer a message which was not dispatched and is not listed in any queue. 209 164 * … … 214 169 static void _ipc_answer_free_call(call_t *call, bool selflocked) 215 170 { 216 answerbox_t *callerbox = call->callerbox;171 answerbox_t *callerbox = &call->sender->answerbox; 217 172 bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox)); 218 173 … … 606 561 ipc_cleanup_call_list(&TASK->answerbox.calls); 607 562 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);622 563 623 564 /* Wait for all answers to asynchronous calls to arrive */ -
kernel/generic/src/ipc/sysipc.c
r45cbcaf4 r14c5005 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 than621 * 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 will629 * 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 beyond650 * 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_UDEBUG660 udebug_stoppable_begin();661 #endif662 rc = ipc_call_sync(phone, call);663 #ifdef CONFIG_UDEBUG664 udebug_stoppable_end();665 #endif666 667 if (rc != EOK) {668 /* The call will be freed by ipc_cleanup(). */669 return rc;670 }671 672 process_answer(call);673 } else674 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 the689 * 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_UDEBUG713 udebug_stoppable_begin();714 #endif715 rc = ipc_call_sync(phone, call);716 #ifdef CONFIG_UDEBUG717 udebug_stoppable_end();718 #endif719 720 if (rc != EOK) {721 /* The call will be freed by ipc_cleanup(). */722 return rc;723 }724 725 process_answer(call);726 } else727 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;733 614 734 615 return 0; -
kernel/generic/src/proc/task.c
r45cbcaf4 r14c5005 156 156 157 157 list_initialize(&task->threads); 158 list_initialize(&task->sync_boxes);159 158 160 159 ipc_answerbox_init(&task->answerbox, task); -
kernel/generic/src/syscall/syscall.c
r45cbcaf4 r14c5005 151 151 152 152 /* IPC related syscalls. */ 153 (syshandler_t) sys_ipc_call_sync_fast,154 (syshandler_t) sys_ipc_call_sync_slow,155 153 (syshandler_t) sys_ipc_call_async_fast, 156 154 (syshandler_t) sys_ipc_call_async_slow, -
uspace/Makefile
r45cbcaf4 r14c5005 58 58 app/tester \ 59 59 app/testread \ 60 app/testwrit \ 60 61 app/tetris \ 61 62 app/trace \ … … 98 99 srv/fs/locfs \ 99 100 srv/fs/ext2fs \ 101 srv/fs/ext4fs \ 100 102 srv/hid/console \ 101 103 srv/hid/s3c24xx_ts \ … … 199 201 lib/nic \ 200 202 lib/ext2 \ 203 lib/ext4 \ 201 204 lib/usb \ 202 205 lib/usbhost \ -
uspace/Makefile.common
r45cbcaf4 r14c5005 115 115 116 116 LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2 117 LIBEXT4_PREFIX = $(LIB_PREFIX)/ext4 117 118 118 119 LIBUSB_PREFIX = $(LIB_PREFIX)/usb -
uspace/app/trace/syscalls.c
r45cbcaf4 r14c5005 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 },57 55 [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, V_HASH }, 58 56 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, V_HASH }, -
uspace/app/trace/trace.c
r45cbcaf4 r14c5005 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 377 320 static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc) 378 321 { … … 408 351 print_sc_args(sc_args, syscall_desc[sc_id].n_args); 409 352 } 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 }418 353 } 419 354 … … 447 382 case SYS_IPC_CALL_ASYNC_SLOW: 448 383 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);455 384 break; 456 385 case SYS_IPC_WAIT: -
uspace/lib/c/generic/async.c
r45cbcaf4 r14c5005 114 114 #include <stdlib.h> 115 115 #include <macros.h> 116 #include "private/libc.h" 116 117 117 118 #define CLIENT_HASH_TABLE_BUCKETS 32 … … 2166 2167 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 2167 2168 { 2168 return ipc_share_in_finalize(callid, src, flags); 2169 return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags, 2170 (sysarg_t) __entry); 2169 2171 } 2170 2172 … … 2233 2235 int async_share_out_finalize(ipc_callid_t callid, void **dst) 2234 2236 { 2235 return ipc_ share_out_finalize(callid,dst);2237 return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst); 2236 2238 } 2237 2239 … … 2317 2319 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 2318 2320 { 2319 return ipc_ data_read_finalize(callid, src,size);2321 return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size); 2320 2322 } 2321 2323 … … 2420 2422 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 2421 2423 { 2422 return ipc_ data_write_finalize(callid, dst,size);2424 return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size); 2423 2425 } 2424 2426 -
uspace/lib/c/generic/ipc.c
r45cbcaf4 r14c5005 48 48 #include <fibril.h> 49 49 #include <macros.h> 50 #include "private/libc.h"51 50 52 51 /** … … 83 82 84 83 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() because90 * 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 }182 84 183 85 /** Send asynchronous message via syscall. … … 611 513 } 612 514 613 /** Request callback connection.614 *615 * The @a task_id and @a phonehash identifiers returned616 * 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 will624 * 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, the684 * call should block. This has to be, however, implemented685 * 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 707 515 /** Hang up a phone. 708 516 * … … 758 566 } 759 567 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_IN789 * calls so that the user doesn't have to remember the meaning of each790 * 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_OUT823 * calls so that the user doesn't have to remember the meaning of each824 * 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_READ855 * calls so that the user doesn't have to remember the meaning of each856 * 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 than861 * 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_WRITE889 * calls so that the user doesn't have to remember the meaning of each890 * 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 904 568 /** Connect to a task specified by id. 905 569 * -
uspace/lib/c/include/ipc/ipc.h
r45cbcaf4 r14c5005 47 47 48 48 typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *); 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 of53 * arguments of payload and n denotes number of return values. Whenever54 * 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 49 186 50 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int); … … 254 118 sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool); 255 119 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 262 120 extern int ipc_hangup(int); 263 121 … … 267 125 sysarg_t, sysarg_t, sysarg_t, unsigned int); 268 126 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 291 127 extern int ipc_connect_kbox(task_id_t); 292 128 -
uspace/srv/devman/devman.c
r45cbcaf4 r14c5005 1052 1052 } 1053 1053 1054 1055 1054 /** Find the device node structure of the device witch has the specified handle. 1056 1055 * … … 1142 1141 fun->state = FUN_INIT; 1143 1142 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); 1186 1198 } 1187 1199 -
uspace/srv/devman/devman.h
r45cbcaf4 r14c5005 174 174 /** State */ 175 175 fun_state_t state; 176 /** Locked while performing reconfiguration operations */ 177 fibril_mutex_t busy_lock; 176 178 177 179 /** The global unique identifier of the function */ … … 279 281 extern void dev_add_ref(dev_node_t *); 280 282 extern void dev_del_ref(dev_node_t *); 283 281 284 extern dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, 282 285 devman_handle_t handle); … … 290 293 extern void fun_add_ref(fun_node_t *); 291 294 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 *); 292 297 extern fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, 293 298 devman_handle_t handle); -
uspace/srv/devman/main.c
r45cbcaf4 r14c5005 432 432 433 433 fun_node_t *fun = create_fun_node(); 434 /* One reference for creation, one for us */ 435 fun_add_ref(fun); 434 436 fun_add_ref(fun); 435 437 fun->ftype = ftype; 438 439 /* 440 * We can lock the function here even when holding the tree because 441 * we know it cannot be held by anyone else yet. 442 */ 443 fun_busy_lock(fun); 436 444 437 445 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 438 446 fibril_rwlock_write_unlock(&tree->rwlock); 439 447 dev_del_ref(pdev); 448 fun_busy_unlock(fun); 449 fun_del_ref(fun); 440 450 delete_fun_node(fun); 441 451 async_answer_0(callid, ENOMEM); … … 450 460 rc = online_function(fun); 451 461 if (rc != EOK) { 452 /* XXX clean up */ 462 /* XXX Set some failed state? */ 463 fun_busy_unlock(fun); 464 fun_del_ref(fun); 453 465 async_answer_0(callid, rc); 454 466 return; 455 467 } 468 469 fun_busy_unlock(fun); 470 fun_del_ref(fun); 456 471 457 472 /* Return device handle to parent's driver. */ … … 522 537 } 523 538 539 fun_busy_lock(fun); 540 524 541 fibril_rwlock_read_lock(&device_tree.rwlock); 525 542 if (fun->dev == NULL || fun->dev->drv != drv) { 526 543 fibril_rwlock_read_unlock(&device_tree.rwlock); 544 fun_busy_unlock(fun); 527 545 fun_del_ref(fun); 528 546 async_answer_0(iid, ENOENT); … … 533 551 rc = online_function(fun); 534 552 if (rc != EOK) { 553 fun_busy_unlock(fun); 535 554 fun_del_ref(fun); 536 555 async_answer_0(iid, (sysarg_t) rc); … … 538 557 } 539 558 559 fun_busy_unlock(fun); 540 560 fun_del_ref(fun); 541 561 … … 559 579 } 560 580 581 fun_busy_lock(fun); 582 561 583 fibril_rwlock_write_lock(&device_tree.rwlock); 562 584 if (fun->dev == NULL || fun->dev->drv != drv) { 585 fun_busy_unlock(fun); 563 586 fun_del_ref(fun); 564 587 async_answer_0(iid, ENOENT); … … 569 592 rc = offline_function(fun); 570 593 if (rc != EOK) { 594 fun_busy_unlock(fun); 571 595 fun_del_ref(fun); 572 596 async_answer_0(iid, (sysarg_t) rc); … … 574 598 } 575 599 600 fun_busy_unlock(fun); 576 601 fun_del_ref(fun); 577 602 async_answer_0(iid, (sysarg_t) EOK); … … 591 616 } 592 617 618 fun_busy_lock(fun); 619 593 620 fibril_rwlock_write_lock(&tree->rwlock); 594 621 … … 598 625 if (fun->state == FUN_REMOVED) { 599 626 fibril_rwlock_write_unlock(&tree->rwlock); 627 fun_busy_unlock(fun); 628 fun_del_ref(fun); 600 629 async_answer_0(callid, ENOENT); 601 630 return; … … 638 667 if (gone_rc == EOK) 639 668 gone_rc = ENOTSUP; 669 fun_busy_unlock(fun); 670 fun_del_ref(fun); 640 671 async_answer_0(callid, gone_rc); 641 672 return; … … 664 695 "service."); 665 696 fibril_rwlock_write_unlock(&tree->rwlock); 697 fun_busy_unlock(fun); 666 698 fun_del_ref(fun); 667 699 async_answer_0(callid, EIO); … … 673 705 remove_fun_node(&device_tree, fun); 674 706 fibril_rwlock_write_unlock(&tree->rwlock); 707 fun_busy_unlock(fun); 675 708 676 709 /* Delete ref added when inserting function into tree */
Note:
See TracChangeset
for help on using the changeset viewer.