Changeset a55d5f9f in mainline
- Timestamp:
- 2007-12-23T21:21:41Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a92da0a
- Parents:
- 654b7db
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/ipc.h
r654b7db ra55d5f9f 280 280 ipc_data_t data; 281 281 282 /** Buffer for IPC_M_DATA_ SEND. */282 /** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */ 283 283 uint8_t *buffer; 284 284 } call_t; -
kernel/generic/src/ipc/ipc.c
r654b7db ra55d5f9f 415 415 while (!list_empty(lst)) { 416 416 call = list_get_instance(lst->next, call_t, link); 417 if (call->buffer) 418 free(call->buffer); 417 419 list_remove(&call->link); 418 420 -
kernel/generic/src/ipc/sysipc.c
r654b7db ra55d5f9f 236 236 IPC_SET_RETVAL(answer->data, rc); 237 237 } 238 } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_READ) { 239 ASSERT(!answer->buffer); 240 if (!IPC_GET_RETVAL(answer->data)) { 241 /* The recipient agreed to send data. */ 242 uintptr_t src = IPC_GET_ARG1(answer->data); 243 uintptr_t dst = IPC_GET_ARG1(*olddata); 244 size_t max_size = IPC_GET_ARG2(*olddata); 245 size_t size = IPC_GET_ARG2(answer->data); 246 if (size <= max_size) { 247 /* 248 * Copy the destination VA so that this piece of 249 * information is not lost. 250 */ 251 IPC_SET_ARG1(answer->data, dst); 252 253 answer->buffer = malloc(size, 0); 254 int rc = copy_from_uspace(answer->buffer, 255 (void *) src, size); 256 if (rc) { 257 IPC_SET_RETVAL(answer->data, rc); 258 free(answer->buffer); 259 answer->buffer = NULL; 260 } 261 } else { 262 IPC_SET_RETVAL(answer->data, ELIMIT); 263 } 264 } 238 265 } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_WRITE) { 239 266 ASSERT(answer->buffer); 240 267 if (!IPC_GET_RETVAL(answer->data)) { 268 /* The recipient agreed to receive data. */ 241 269 int rc; 242 270 uintptr_t dst; 243 271 uintptr_t size; 272 uintptr_t max_size; 244 273 245 274 dst = IPC_GET_ARG1(answer->data); 246 275 size = IPC_GET_ARG3(answer->data); 247 248 rc = copy_to_uspace((void *) dst, answer->buffer, size); 249 if (rc != 0) 250 IPC_SET_RETVAL(answer->data, rc); 276 max_size = IPC_GET_ARG3(*olddata); 277 278 if (size <= max_size) { 279 rc = copy_to_uspace((void *) dst, 280 answer->buffer, size); 281 if (rc) 282 IPC_SET_RETVAL(answer->data, rc); 283 } else { 284 IPC_SET_RETVAL(answer->data, ELIMIT); 285 } 251 286 } 252 287 free(answer->buffer); … … 285 320 IPC_SET_ARG2(call->data, size); 286 321 break; 322 case IPC_M_DATA_READ: 323 size = IPC_GET_ARG2(call->data); 324 if ((size <= 0 || (size > DATA_XFER_LIMIT))) 325 return ELIMIT; 326 break; 287 327 case IPC_M_DATA_WRITE: 288 328 src = IPC_GET_ARG2(call->data); … … 325 365 IPC_SET_ARG5(call->data, call->priv); 326 366 } 367 368 if (call->buffer) { 369 /* This must be an affirmative answer to IPC_M_DATA_READ. */ 370 uintptr_t dst = IPC_GET_ARG1(call->data); 371 size_t size = IPC_GET_ARG2(call->data); 372 int rc = copy_to_uspace((void *) dst, call->buffer, size); 373 if (rc) 374 IPC_SET_RETVAL(call->data, rc); 375 free(call->buffer); 376 call->buffer = NULL; 377 } 327 378 } 328 379 -
uspace/lib/libc/generic/ipc.c
r654b7db ra55d5f9f 667 667 } 668 668 669 /** Wrapper for making IPC_M_DATA_READ calls. 670 * 671 * @param phoneid Phone that will be used to contact the receiving side. 672 * @param dst Address of the beginning of the destination buffer. 673 * @param size Size of the destination buffer. 674 * 675 * @return Zero on success or a negative error code from errno.h. 676 */ 677 int ipc_data_read_send(int phoneid, void *dst, size_t size) 678 { 679 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, 680 (ipcarg_t) size); 681 } 682 683 /** Wrapper for receiving the IPC_M_DATA_READ calls. 684 * 685 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls 686 * so that the user doesn't have to remember the meaning of each IPC argument. 687 * 688 * So far, this wrapper is to be used from within a connection fibril. 689 * 690 * @param callid Storage where the hash of the IPC_M_DATA_READ call will 691 * be stored. 692 * @param size Storage where the maximum size will be stored. 693 * 694 * @return Non-zero on success, zero on failure. 695 */ 696 int ipc_data_read_receive(ipc_callid_t *callid, size_t *size) 697 { 698 ipc_call_t data; 699 700 assert(callid); 701 702 *callid = async_get_call(&data); 703 if (IPC_GET_METHOD(data) != IPC_M_DATA_READ) 704 return 0; 705 assert(size); 706 *size = (size_t) IPC_GET_ARG2(data); 707 return 1; 708 } 709 710 /** Wrapper for answering the IPC_M_DATA_READ calls. 711 * 712 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 713 * so that the user doesn't have to remember the meaning of each IPC argument. 714 * 715 * @param callid Hash of the IPC_M_DATA_READ call to answer. 716 * @param src Source address for the IPC_M_DATA_READ call. 717 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 718 * the maximum size announced by the sender. 719 * 720 * @return Zero on success or a value from @ref errno.h on failure. 721 */ 722 int ipc_data_read_deliver(ipc_callid_t callid, void *src, size_t size) 723 { 724 return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) size); 725 } 726 669 727 /** Wrapper for making IPC_M_DATA_WRITE calls. 670 728 * … … 724 782 * @return Zero on success or a value from @ref errno.h on failure. 725 783 */ 726 i pcarg_t ipc_data_write_deliver(ipc_callid_t callid, void *dst, size_t size)784 int ipc_data_write_deliver(ipc_callid_t callid, void *dst, size_t size) 727 785 { 728 786 return ipc_answer_3(callid, EOK, (ipcarg_t) dst, 0, (ipcarg_t) size); -
uspace/lib/libc/include/ipc/ipc.h
r654b7db ra55d5f9f 261 261 extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, 262 262 ipcarg_t arg1, ipcarg_t arg2, int mode); 263 264 265 extern int ipc_data_read_send(int phoneid, void *dst, size_t size); 266 extern int ipc_data_read_receive(ipc_callid_t *callid, size_t *size); 267 extern int ipc_data_read_deliver(ipc_callid_t callid, void *src, size_t size); 263 268 extern int ipc_data_write_send(int phoneid, void *src, size_t size); 264 269 extern int ipc_data_write_receive(ipc_callid_t *callid, void **dst, 265 270 size_t *size); 266 extern ipcarg_t ipc_data_write_deliver(ipc_callid_t callid, void *dst, 267 size_t size); 271 extern int ipc_data_write_deliver(ipc_callid_t callid, void *dst, size_t size); 268 272 269 273 #endif
Note:
See TracChangeset
for help on using the changeset viewer.