2
* Copyright (c) 2006 Ondrej Palkovsky
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
/** @addtogroup libcipc IPC
35
* @brief HelenOS uspace IPC
50
#include <kernel/synch/synch.h>
56
* Structures of this type are used for keeping track of sent asynchronous calls
57
* and queing unsent calls.
62
ipc_async_callback_t callback;
71
fid_t fid; /**< Fibril waiting for sending this call. */
74
LIST_INITIALIZE(dispatched_calls);
76
/** List of asynchronous calls that were not accepted by kernel.
78
* It is protected by async_futex, because if the call cannot be sent into the
79
* kernel, the async framework is used automatically.
81
LIST_INITIALIZE(queued_calls);
83
static atomic_t ipc_futex = FUTEX_INITIALIZER;
85
/** Make a fast synchronous call.
87
* Only three payload arguments can be passed using this function. However, this
88
* function is faster than the generic ipc_call_sync_slow() because the payload
89
* is passed directly in registers.
91
* @param phoneid Phone handle for the call.
92
* @param method Requested method.
93
* @param arg1 Service-defined payload argument.
94
* @param arg2 Service-defined payload argument.
95
* @param arg3 Service-defined payload argument.
96
* @param result1 If non-NULL, the return ARG1 will be stored there.
97
* @param result2 If non-NULL, the return ARG2 will be stored there.
98
* @param result3 If non-NULL, the return ARG3 will be stored there.
99
* @param result4 If non-NULL, the return ARG4 will be stored there.
100
* @param result5 If non-NULL, the return ARG5 will be stored there.
102
* @return Negative values represent errors returned by IPC.
103
* Otherwise the RETVAL of the answer is returned.
106
ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
107
ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3,
108
ipcarg_t *result4, ipcarg_t *result5)
113
callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
114
arg2, arg3, (sysarg_t) &resdata);
118
*result1 = IPC_GET_ARG1(resdata);
120
*result2 = IPC_GET_ARG2(resdata);
122
*result3 = IPC_GET_ARG3(resdata);
124
*result4 = IPC_GET_ARG4(resdata);
126
*result5 = IPC_GET_ARG5(resdata);
128
return IPC_GET_RETVAL(resdata);
131
/** Make a synchronous call transmitting 5 arguments of payload.
133
* @param phoneid Phone handle for the call.
134
* @param method Requested 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.
146
* @return Negative value means IPC error.
147
* Otherwise the RETVAL of the answer.
150
ipc_call_sync_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
151
ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, ipcarg_t *result1,
152
ipcarg_t *result2, ipcarg_t *result3, ipcarg_t *result4, ipcarg_t *result5)
157
IPC_SET_METHOD(data, method);
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);
164
callres = __SYSCALL3(SYS_IPC_CALL_SYNC_SLOW, phoneid, (sysarg_t) &data,
170
*result1 = IPC_GET_ARG1(data);
172
*result2 = IPC_GET_ARG2(data);
174
*result3 = IPC_GET_ARG3(data);
176
*result4 = IPC_GET_ARG4(data);
178
*result5 = IPC_GET_ARG5(data);
180
return IPC_GET_RETVAL(data);
183
/** Syscall to send asynchronous message.
185
* @param phoneid Phone handle for the call.
186
* @param data Call data with the request.
188
* @return Hash of the call or an error code.
190
static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
192
return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);
195
/** Prolog to ipc_call_async_*() functions.
197
* @param private Argument for the answer/error callback.
198
* @param callback Answer/error callback.
200
* @return New, partially initialized async_call structure or NULL.
202
static inline async_call_t *ipc_prepare_async(void *private,
203
ipc_async_callback_t callback)
207
call = malloc(sizeof(*call));
210
callback(private, ENOMEM, NULL);
213
call->callback = callback;
214
call->private = private;
219
/** Epilogue of ipc_call_async_*() functions.
221
* @param callid Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
222
* @param phoneid Phone handle through which the call was made.
223
* @param call async_call structure returned by ipc_prepare_async().
224
* @param can_preempt If non-zero, the current fibril can be preempted in this
227
static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
228
async_call_t *call, int can_preempt)
230
if (!call) { /* Nothing to do regardless if failed or not */
231
futex_up(&ipc_futex);
235
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
236
futex_up(&ipc_futex);
237
/* Call asynchronous handler with error code */
239
call->callback(call->private, ENOENT, NULL);
244
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
245
futex_up(&ipc_futex);
247
call->u.msg.phoneid = phoneid;
249
futex_down(&async_futex);
250
list_append(&call->list, &queued_calls);
253
call->fid = fibril_get_id();
254
fibril_switch(FIBRIL_TO_MANAGER);
255
/* Async futex unlocked by previous call */
258
futex_up(&async_futex);
262
call->u.callid = callid;
263
/* Add call to the list of dispatched calls */
264
list_append(&call->list, &dispatched_calls);
265
futex_up(&ipc_futex);
269
/** Make a fast asynchronous call.
271
* This function can only handle four arguments of payload. It is, however,
272
* faster than the more generic ipc_call_async_slow().
274
* Note that this function is a void function.
275
* During normal opertation, answering this call will trigger the callback.
276
* In case of fatal error, call the callback handler with the proper error code.
277
* If the call cannot be temporarily made, queue it.
279
* @param phoneid Phone handle for the call.
280
* @param method Requested method.
281
* @param arg1 Service-defined payload argument.
282
* @param arg2 Service-defined payload argument.
283
* @param arg3 Service-defined payload argument.
284
* @param arg4 Service-defined payload argument.
285
* @param private Argument to be passed to the answer/error callback.
286
* @param callback Answer or error callback.
287
* @param can_preempt If non-zero, the current fibril will be preempted in
288
* case the kernel temporarily refuses to accept more
289
* asynchronous calls.
291
void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
292
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private,
293
ipc_async_callback_t callback, int can_preempt)
295
async_call_t *call = NULL;
299
call = ipc_prepare_async(private, callback);
305
* We need to make sure that we get callid before another thread
306
* accesses the queue again.
308
futex_down(&ipc_futex);
309
callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
312
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
314
call = ipc_prepare_async(private, callback);
318
IPC_SET_METHOD(call->u.msg.data, method);
319
IPC_SET_ARG1(call->u.msg.data, arg1);
320
IPC_SET_ARG2(call->u.msg.data, arg2);
321
IPC_SET_ARG3(call->u.msg.data, arg3);
322
IPC_SET_ARG4(call->u.msg.data, arg4);
324
* To achieve deterministic behavior, we always zero out the
325
* arguments that are beyond the limits of the fast version.
327
IPC_SET_ARG5(call->u.msg.data, 0);
329
ipc_finish_async(callid, phoneid, call, can_preempt);
332
/** Make an asynchronous call transmitting the entire payload.
334
* Note that this function is a void function.
335
* During normal opertation, answering this call will trigger the callback.
336
* In case of fatal error, call the callback handler with the proper error code.
337
* If the call cannot be temporarily made, queue it.
339
* @param phoneid Phone handle for the call.
340
* @param method Requested method.
341
* @param arg1 Service-defined payload argument.
342
* @param arg2 Service-defined payload argument.
343
* @param arg3 Service-defined payload argument.
344
* @param arg4 Service-defined payload argument.
345
* @param arg5 Service-defined payload argument.
346
* @param private Argument to be passed to the answer/error callback.
347
* @param callback Answer or error callback.
348
* @param can_preempt If non-zero, the current fibril will be preempted in
349
* case the kernel temporarily refuses to accept more
350
* asynchronous calls.
353
void ipc_call_async_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
354
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, void *private,
355
ipc_async_callback_t callback, int can_preempt)
360
call = ipc_prepare_async(private, callback);
364
IPC_SET_METHOD(call->u.msg.data, method);
365
IPC_SET_ARG1(call->u.msg.data, arg1);
366
IPC_SET_ARG2(call->u.msg.data, arg2);
367
IPC_SET_ARG3(call->u.msg.data, arg3);
368
IPC_SET_ARG4(call->u.msg.data, arg4);
369
IPC_SET_ARG5(call->u.msg.data, arg5);
371
* We need to make sure that we get callid before another thread
372
* accesses the queue again.
374
futex_down(&ipc_futex);
375
callid = _ipc_call_async(phoneid, &call->u.msg.data);
377
ipc_finish_async(callid, phoneid, call, can_preempt);
381
/** Answer a received call - fast version.
383
* The fast answer makes use of passing retval and first four arguments in
384
* registers. If you need to return more, use the ipc_answer_slow() instead.
386
* @param callid Hash of the call being answered.
387
* @param retval Return value.
388
* @param arg1 First return argument.
389
* @param arg2 Second return argument.
390
* @param arg3 Third return argument.
391
* @param arg4 Fourth return argument.
393
* @return Zero on success or a value from @ref errno.h on failure.
395
ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval, ipcarg_t arg1,
396
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4)
398
return __SYSCALL6(SYS_IPC_ANSWER_FAST, callid, retval, arg1, arg2, arg3,
402
/** Answer a received call - slow full version.
404
* @param callid Hash of the call being answered.
405
* @param retval Return value.
406
* @param arg1 First return argument.
407
* @param arg2 Second return argument.
408
* @param arg3 Third return argument.
409
* @param arg4 Fourth return argument.
410
* @param arg5 Fifth return argument.
412
* @return Zero on success or a value from @ref errno.h on failure.
414
ipcarg_t ipc_answer_slow(ipc_callid_t callid, ipcarg_t retval, ipcarg_t arg1,
415
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5)
419
IPC_SET_RETVAL(data, retval);
420
IPC_SET_ARG1(data, arg1);
421
IPC_SET_ARG2(data, arg2);
422
IPC_SET_ARG3(data, arg3);
423
IPC_SET_ARG4(data, arg4);
424
IPC_SET_ARG5(data, arg5);
426
return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data);
430
/** Try to dispatch queued calls from the async queue. */
431
static void try_dispatch_queued_calls(void)
437
* Integrate intelligently ipc_futex, so that it is locked during
438
* ipc_call_async_*(), until it is added to dispatched_calls.
440
futex_down(&async_futex);
441
while (!list_empty(&queued_calls)) {
442
call = list_get_instance(queued_calls.next, async_call_t, list);
443
callid = _ipc_call_async(call->u.msg.phoneid,
445
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
448
list_remove(&call->list);
450
futex_up(&async_futex);
452
fibril_add_ready(call->fid);
454
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
456
call->callback(call->private, ENOENT, NULL);
459
call->u.callid = callid;
460
futex_down(&ipc_futex);
461
list_append(&call->list, &dispatched_calls);
462
futex_up(&ipc_futex);
464
futex_down(&async_futex);
466
futex_up(&async_futex);
469
/** Handle a received answer.
471
* Find the hash of the answer and call the answer callback.
473
* @todo Make it use hash table.
475
* @param callid Hash of the received answer.
476
* The answer has the same hash as the request OR'ed with
477
* the IPC_CALLID_ANSWERED bit.
478
* @param data Call data of the answer.
480
static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
485
callid &= ~IPC_CALLID_ANSWERED;
487
futex_down(&ipc_futex);
488
for (item = dispatched_calls.next; item != &dispatched_calls;
490
call = list_get_instance(item, async_call_t, list);
491
if (call->u.callid == callid) {
492
list_remove(&call->list);
493
futex_up(&ipc_futex);
495
call->callback(call->private,
496
IPC_GET_RETVAL(*data), data);
501
futex_up(&ipc_futex);
505
/** Wait for a first call to come.
507
* @param call Storage where the incoming call data will be stored.
508
* @param usec Timeout in microseconds
509
* @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
511
* @return Hash of the call. Note that certain bits have special
512
* meaning. IPC_CALLID_ANSWERED will be set in an answer
513
* and IPC_CALLID_NOTIFICATION is used for notifications.
516
ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags)
520
callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
521
/* Handle received answers */
522
if (callid & IPC_CALLID_ANSWERED) {
523
handle_answer(callid, call);
524
try_dispatch_queued_calls();
530
/** Wait some time for an IPC call.
532
* The call will return after an answer is received.
534
* @param call Storage where the incoming call data will be stored.
535
* @param usec Timeout in microseconds.
537
* @return Hash of the answer.
539
ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec)
544
callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
545
} while (callid & IPC_CALLID_ANSWERED);
550
/** Check if there is an IPC call waiting to be picked up.
552
* @param call Storage where the incoming call will be stored.
553
* @return Hash of the answer.
555
ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
560
callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
561
SYNCH_FLAGS_NON_BLOCKING);
562
} while (callid & IPC_CALLID_ANSWERED);
567
/** Ask destination to do a callback connection.
569
* @param phoneid Phone handle used for contacting the other side.
570
* @param arg1 Service-defined argument.
571
* @param arg2 Service-defined argument.
572
* @param arg3 Service-defined argument.
573
* @param phonehash Storage where the library will store an opaque
574
* identifier of the phone that will be used for incoming
575
* calls. This identifier can be used for connection
578
* @return Zero on success or a negative error code.
580
int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
583
return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
584
arg3, NULL, NULL, NULL, NULL, phonehash);
587
/** Ask through phone for a new connection to some service.
589
* @param phoneid Phone handle used for contacting the other side.
590
* @param arg1 User defined argument.
591
* @param arg2 User defined argument.
592
* @param arg3 User defined argument.
594
* @return New phone handle on success or a negative error code.
596
int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3)
601
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
602
NULL, NULL, NULL, NULL, &newphid);
608
/** Ask through phone for a new connection to some service.
610
* If the connection is not available at the moment, the
613
* @param phoneid Phone handle used for contacting the other side.
614
* @param arg1 User defined argument.
615
* @param arg2 User defined argument.
616
* @param arg3 User defined argument.
618
* @return New phone handle on success or a negative error code.
620
int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3)
625
res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
626
IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
634
* @param phoneid Handle of the phone to be hung up.
636
* @return Zero on success or a negative error code.
638
int ipc_hangup(int phoneid)
640
return __SYSCALL1(SYS_IPC_HANGUP, phoneid);
643
/** Register IRQ notification.
645
* @param inr IRQ number.
646
* @param devno Device number of the device generating inr.
647
* @param method Use this method for notifying me.
648
* @param ucode Top-half pseudocode handler.
650
* @return Value returned by the kernel.
652
int ipc_register_irq(int inr, int devno, int method, irq_code_t *ucode)
654
return __SYSCALL4(SYS_IPC_REGISTER_IRQ, inr, devno, method,
658
/** Unregister IRQ notification.
660
* @param inr IRQ number.
661
* @param devno Device number of the device generating inr.
663
* @return Value returned by the kernel.
665
int ipc_unregister_irq(int inr, int devno)
667
return __SYSCALL2(SYS_IPC_UNREGISTER_IRQ, inr, devno);
670
/** Forward a received call to another destination.
672
* @param callid Hash of the call to forward.
673
* @param phoneid Phone handle to use for forwarding.
674
* @param method New method for the forwarded call.
675
* @param arg1 New value of the first argument for the forwarded call.
676
* @param arg2 New value of the second argument for the forwarded call.
677
* @param mode Flags specifying mode of the forward operation.
679
* @return Zero on success or an error code.
681
* For non-system methods, the old method, arg1 and arg2 are rewritten by the
682
* new values. For system methods, the new method, arg1 and arg2 are written
683
* to the old arg1, arg2 and arg3, respectivelly. Calls with immutable
684
* methods are forwarded verbatim.
686
int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method,
687
ipcarg_t arg1, ipcarg_t arg2, int mode)
689
return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, method, arg1,
694
int ipc_forward_slow(ipc_callid_t callid, int phoneid, int method,
695
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
700
IPC_SET_METHOD(data, method);
701
IPC_SET_ARG1(data, arg1);
702
IPC_SET_ARG2(data, arg2);
703
IPC_SET_ARG3(data, arg3);
704
IPC_SET_ARG4(data, arg4);
705
IPC_SET_ARG5(data, arg5);
707
return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode);
710
/** Wrapper for making IPC_M_SHARE_IN calls.
712
* @param phoneid Phone that will be used to contact the receiving side.
713
* @param dst Destination address space area base.
714
* @param size Size of the destination address space area.
715
* @param arg User defined argument.
716
* @param flags Storage where the received flags will be stored. Can be
719
* @return Zero on success or a negative error code from errno.h.
721
int ipc_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg,
726
res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
727
(ipcarg_t) size, arg, NULL, &tmp_flags);
733
/** Wrapper for receiving the IPC_M_SHARE_IN calls.
735
* This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
736
* so that the user doesn't have to remember the meaning of each IPC argument.
738
* So far, this wrapper is to be used from within a connection fibril.
740
* @param callid Storage where the hash of the IPC_M_SHARE_IN call will
742
* @param size Destination address space area size.
744
* @return Non-zero on success, zero on failure.
746
int ipc_share_in_receive(ipc_callid_t *callid, size_t *size)
753
*callid = async_get_call(&data);
754
if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN)
756
*size = (size_t) IPC_GET_ARG2(data);
760
/** Wrapper for answering the IPC_M_SHARE_IN calls.
762
* This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
763
* so that the user doesn't have to remember the meaning of each IPC argument.
765
* @param callid Hash of the IPC_M_DATA_READ call to answer.
766
* @param src Source address space base.
767
* @param flags Flags to be used for sharing. Bits can be only cleared.
769
* @return Zero on success or a value from @ref errno.h on failure.
771
int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags)
773
return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) flags);
776
/** Wrapper for making IPC_M_SHARE_OUT calls.
778
* @param phoneid Phone that will be used to contact the receiving side.
779
* @param src Source address space area base address.
780
* @param flags Flags to be used for sharing. Bits can be only cleared.
782
* @return Zero on success or a negative error code from errno.h.
784
int ipc_share_out_start(int phoneid, void *src, int flags)
786
return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,
790
/** Wrapper for receiving the IPC_M_SHARE_OUT calls.
792
* This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
793
* so that the user doesn't have to remember the meaning of each IPC argument.
795
* So far, this wrapper is to be used from within a connection fibril.
797
* @param callid Storage where the hash of the IPC_M_SHARE_OUT call will
799
* @param size Storage where the source address space area size will be
801
* @param flags Storage where the sharing flags will be stored.
803
* @return Non-zero on success, zero on failure.
805
int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
813
*callid = async_get_call(&data);
814
if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT)
816
*size = (size_t) IPC_GET_ARG2(data);
817
*flags = (int) IPC_GET_ARG3(data);
821
/** Wrapper for answering the IPC_M_SHARE_OUT calls.
823
* This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
824
* so that the user doesn't have to remember the meaning of each IPC argument.
826
* @param callid Hash of the IPC_M_DATA_WRITE call to answer.
827
* @param dst Destination address space area base address.
829
* @return Zero on success or a value from @ref errno.h on failure.
831
int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
833
return ipc_answer_1(callid, EOK, (ipcarg_t) dst);
837
/** Wrapper for making IPC_M_DATA_READ calls.
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.
843
* @return Zero on success or a negative error code from errno.h.
845
int ipc_data_read_start(int phoneid, void *dst, size_t size)
847
return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,
851
/** Wrapper for receiving the IPC_M_DATA_READ calls.
853
* This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls
854
* so that the user doesn't have to remember the meaning of each IPC argument.
856
* So far, this wrapper is to be used from within a connection fibril.
858
* @param callid Storage where the hash of the IPC_M_DATA_READ call will
860
* @param size Storage where the maximum size will be stored. Can be
863
* @return Non-zero on success, zero on failure.
865
int ipc_data_read_receive(ipc_callid_t *callid, size_t *size)
871
*callid = async_get_call(&data);
872
if (IPC_GET_METHOD(data) != IPC_M_DATA_READ)
875
*size = (size_t) IPC_GET_ARG2(data);
879
/** Wrapper for answering the IPC_M_DATA_READ calls.
881
* This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
882
* so that the user doesn't have to remember the meaning of each IPC argument.
884
* @param callid Hash of the IPC_M_DATA_READ call to answer.
885
* @param src Source address for the IPC_M_DATA_READ call.
886
* @param size Size for the IPC_M_DATA_READ call. Can be smaller than
887
* the maximum size announced by the sender.
889
* @return Zero on success or a value from @ref errno.h on failure.
891
int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
893
return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) size);
896
/** Wrapper for making IPC_M_DATA_WRITE calls.
898
* @param phoneid Phone that will be used to contact the receiving side.
899
* @param src Address of the beginning of the source buffer.
900
* @param size Size of the source buffer.
902
* @return Zero on success or a negative error code from errno.h.
904
int ipc_data_write_start(int phoneid, const void *src, size_t size)
906
return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
910
/** Wrapper for receiving the IPC_M_DATA_WRITE calls.
912
* This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls
913
* so that the user doesn't have to remember the meaning of each IPC argument.
915
* So far, this wrapper is to be used from within a connection fibril.
917
* @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
919
* @param size Storage where the suggested size will be stored. May be
922
* @return Non-zero on success, zero on failure.
924
int ipc_data_write_receive(ipc_callid_t *callid, size_t *size)
930
*callid = async_get_call(&data);
931
if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
934
*size = (size_t) IPC_GET_ARG2(data);
938
/** Wrapper for answering the IPC_M_DATA_WRITE calls.
940
* This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
941
* so that the user doesn't have to remember the meaning of each IPC argument.
943
* @param callid Hash of the IPC_M_DATA_WRITE call to answer.
944
* @param dst Final destination address for the IPC_M_DATA_WRITE call.
945
* @param size Final size for the IPC_M_DATA_WRITE call.
947
* @return Zero on success or a value from @ref errno.h on failure.
949
int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
951
return ipc_answer_2(callid, EOK, (ipcarg_t) dst, (ipcarg_t) size);
954
#include <kernel/syscall/sysarg64.h>
955
/** Connect to a task specified by id.
957
int ipc_connect_kbox(task_id_t id)
961
arg.value = (unsigned long long) id;
963
return __SYSCALL1(SYS_IPC_CONNECT_KBOX, (sysarg_t) &arg);