Changeset 8b243f2 in mainline for kernel/generic/src/ipc/sysipc.c
- Timestamp:
- 2007-06-17T19:34:36Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bd72c3e9
- Parents:
- 4680ef5
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/sysipc.c
r4680ef5 r8b243f2 50 50 #include <print.h> 51 51 52 #define GET_CHECK_PHONE(phone, phoneid, err) { \ 53 if (phoneid > IPC_MAX_PHONES) { err; } \ 54 phone = &TASK->phones[phoneid]; \ 55 } 56 57 #define STRUCT_TO_USPACE(dst, src) copy_to_uspace(dst, src, sizeof(*(src))) 58 59 /** Return true if the method is a system method */ 52 #define GET_CHECK_PHONE(phone, phoneid, err) \ 53 { \ 54 if (phoneid > IPC_MAX_PHONES) { \ 55 err; \ 56 } \ 57 phone = &TASK->phones[phoneid]; \ 58 } 59 60 #define STRUCT_TO_USPACE(dst, src) copy_to_uspace(dst, src, sizeof(*(src))) 61 62 /** Decide if the method is a system method. 63 * 64 * @param method Method to be decided. 65 * 66 * @return Return 1 if the method is a system method. 67 * Otherwise return 0. 68 */ 60 69 static inline int is_system_method(unative_t method) 61 70 { … … 65 74 } 66 75 67 /** Return true if the message with this method is forwardable76 /** Decide if the message with this method is forwardable. 68 77 * 69 78 * - some system messages may be forwarded, for some of them 70 79 * it is useless 80 * 81 * @param method Method to be decided. 82 * 83 * @return Return 1 if the method is forwardable. 84 * Otherwise return 0. 71 85 */ 72 86 static inline int is_forwardable(unative_t method) … … 78 92 } 79 93 80 /****************************************************/ 81 /* Functions that preprocess answer before sending 82 * it to the recepient 83 */ 84 85 /** Return true if the caller (ipc_answer) should save 86 * the old call contents for answer_preprocess 94 95 /*********************************************************************** 96 * Functions that preprocess answer before sending it to the recepient. 97 ***********************************************************************/ 98 99 /** Decide if the caller (e.g. ipc_answer()) should save the old call contents 100 * for answer_preprocess(). 101 * 102 * @param call Call structure to be decided. 103 * 104 * @return Return 1 if the old call contents should be saved. 105 * Return 0 otherwise. 87 106 */ 88 107 static inline int answer_need_old(call_t *call) … … 99 118 } 100 119 101 /** Interpret process answer as control information 102 * 103 * This function is called directly after sys_ipc_answer 120 /** Interpret process answer as control information. 121 * 122 * This function is called directly after sys_ipc_answer(). 123 * 124 * @param answer Call structure with the answer. 125 * @param olddata Saved data of the request. 126 * 127 * @return Return 0 on success or an error code. 104 128 */ 105 129 static inline int answer_preprocess(call_t *answer, ipc_data_t *olddata) … … 132 156 /* The connection was accepted */ 133 157 phone_connect(phoneid, &answer->sender->answerbox); 134 /* Set 'phone identification' as arg3 of response */158 /* Set 'phone hash' as arg3 of response */ 135 159 IPC_SET_ARG3(answer->data, 136 160 (unative_t) &TASK->phones[phoneid]); … … 182 206 } 183 207 184 /** Called before the request is sent 185 * 186 * @return 0 - no error, -1 - report error to user 208 /** Called before the request is sent. 209 * 210 * @param call Call structure with the request. 211 * 212 * @return Return 0 on success, ELIMIT or EPERM on error. 187 213 */ 188 214 static int request_preprocess(call_t *call) … … 203 229 case IPC_M_AS_AREA_SEND: 204 230 size = as_get_size(IPC_GET_ARG1(call->data)); 205 if (!size) {231 if (!size) 206 232 return EPERM; 207 }208 233 IPC_SET_ARG2(call->data, size); 209 234 break; … … 214 239 } 215 240 216 /****************************************************/ 217 /* Functions called to process received call/answer 218 * before passing to uspace 219 */ 220 221 /** Do basic kernel processing of received call answer */ 241 /******************************************************************************* 242 * Functions called to process received call/answer before passing it to uspace. 243 *******************************************************************************/ 244 245 /** Do basic kernel processing of received call answer. 246 * 247 * @param call Call structure with the answer. 248 */ 222 249 static void process_answer(call_t *call) 223 250 { … … 234 261 } 235 262 236 /** Do basic kernel processing of received call request 237 * 238 * @return 0 - the call should be passed to userspace, 1 - ignore call 263 /** Do basic kernel processing of received call request. 264 * 265 * @param box Destination answerbox structure. 266 * @param call Call structure with the request. 267 * 268 * @return Return 0 if the call should be passed to userspace. 269 * Return -1 if the call should be ignored. 239 270 */ 240 271 static int process_request(answerbox_t *box, call_t *call) … … 246 277 if (phoneid < 0) { /* Failed to allocate phone */ 247 278 IPC_SET_RETVAL(call->data, ELIMIT); 248 ipc_answer(box, call);279 ipc_answer(box, call); 249 280 return -1; 250 281 } … … 254 285 } 255 286 256 /** Send a call over IPC, wait for reply, return to user 257 * 258 * @return Call identification, returns -1 on fatal error, 259 -2 on 'Too many async request, handle answers first 287 /** Make a fast call over IPC, wait for reply and return to user. 288 * 289 * This function can handle only one argument of payload, but is faster than 290 * the generic function (i.e. sys_ipc_call_sync()). 291 * 292 * @param phoneid Phone handle for the call. 293 * @param method Method of the call. 294 * @param arg1 Service-defined payload argument. 295 * @param data Address of userspace structure where the reply call will 296 * be stored. 297 * 298 * @return Returns 0 on success. 299 * Return ENOENT if there is no such phone handle. 260 300 */ 261 301 unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method, … … 272 312 IPC_SET_ARG1(call.data, arg1); 273 313 274 if (!(res =request_preprocess(&call))) {314 if (!(res = request_preprocess(&call))) { 275 315 ipc_call_sync(phone, &call); 276 316 process_answer(&call); 277 } else 317 } else { 278 318 IPC_SET_RETVAL(call.data, res); 319 } 279 320 STRUCT_TO_USPACE(&data->args, &call.data.args); 280 321 … … 282 323 } 283 324 284 /** Synchronous IPC call allowing to send whole message */ 325 /** Make a synchronous IPC call allowing to transmit the entire payload. 326 * 327 * @param phoneid Phone handle for the call. 328 * @param question Userspace address of call data with the request. 329 * @param reply Userspace address of call data where to store the answer. 330 * 331 * @return Zero on success or an error code. 332 */ 285 333 unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question, 286 334 ipc_data_t *reply) … … 299 347 GET_CHECK_PHONE(phone, phoneid, return ENOENT); 300 348 301 if (!(res =request_preprocess(&call))) {349 if (!(res = request_preprocess(&call))) { 302 350 ipc_call_sync(phone, &call); 303 351 process_answer(&call); … … 312 360 } 313 361 314 /** Check that the task did not exceed allowed limit315 * 316 * @return 0 - Limit OK, -1 - limit exceeded362 /** Check that the task did not exceed the allowed limit of asynchronous calls. 363 * 364 * @return Return 0 if limit not reached or -1 if limit exceeded. 317 365 */ 318 366 static int check_call_limit(void) … … 325 373 } 326 374 327 /** Send an asynchronous call over ipc 328 * 329 * @return Call identification, returns -1 on fatal error, 330 -2 on 'Too many async request, handle answers first 375 /** Make a fast asynchronous call over IPC. 376 * 377 * This function can only handle two arguments of payload, but is faster than 378 * the generic function sys_ipc_call_async(). 379 * 380 * @param phoneid Phone handle for the call. 381 * @param method Method of the call. 382 * @param arg1 Service-defined payload argument. 383 * @param arg2 Service-defined payload argument. 384 * 385 * @return Return call hash on success. 386 * Return IPC_CALLRET_FATAL in case of a fatal error and 387 * IPC_CALLRET_TEMPORARY if there are too many pending 388 * asynchronous requests; answers should be handled first. 331 389 */ 332 390 unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method, … … 356 414 } 357 415 358 /** Synchronous IPC call allowing to send whole message 359 * 360 * @return The same as sys_ipc_call_async 416 /** Make an asynchronous IPC call allowing to transmit the entire payload. 417 * 418 * @param phoneid Phone handle for the call. 419 * @param data Userspace address of call data with the request. 420 * 421 * @return See sys_ipc_call_async_fast(). 361 422 */ 362 423 unative_t sys_ipc_call_async(unative_t phoneid, ipc_data_t *data) … … 387 448 } 388 449 389 /** Forward received call to another destination 390 * 391 * The arg1 and arg2 are changed in the forwarded message 450 /** Forward a received call to another destination. 451 * 452 * @param callid Hash of the call to forward. 453 * @param phoneid Phone handle to use for forwarding. 454 * @param method New method to use for the forwarded call. 455 * @param arg1 New value of the first argument for the forwarded call. 456 * 457 * @return Return 0 on succes, otherwise return an error code. 458 * 459 * In case the original method is a system method, ARG1 and ARG2 are overwritten 460 * in the forwarded message with the new method and the new arg1, respectively. 461 * Otherwise the METHOD and ARG1 are rewritten with the new method and arg1, 462 * respectively. 392 463 * 393 464 * Warning: If implementing non-fast version, make sure that 394 * arg3 is not rewritten for certain system IPC465 * ARG3 is not rewritten for certain system IPC 395 466 */ 396 467 unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, … … 435 506 } 436 507 437 /** Send IPC answer */ 508 /** Answer an IPC call - fast version. 509 * 510 * This function can handle only two return arguments of payload, but is faster 511 * than the generic sys_ipc_answer(). 512 * 513 * @param callid Hash of the call to be answered. 514 * @param retval Return value of the answer. 515 * @param arg1 Service-defined return value. 516 * @param arg2 Service-defined return value. 517 * 518 * @return Return 0 on success, otherwise return an error code. 519 */ 438 520 unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval, 439 521 unative_t arg1, unative_t arg2) … … 466 548 } 467 549 468 /** Send IPC answer */ 550 /** Answer an IPC call. 551 * 552 * @param callid Hash of the call to be answered. 553 * @param data Userspace address of call data with the answer. 554 * 555 * @return Return 0 on success, otherwise return an error code. 556 */ 469 557 unative_t sys_ipc_answer(unative_t callid, ipc_data_t *data) 470 558 { … … 498 586 } 499 587 500 /** Hang up the phone 501 * 588 /** Hang up a phone. 589 * 590 * @param Phone handle of the phone to be hung up. 591 * 592 * @return Return 0 on success or an error code. 502 593 */ 503 594 unative_t sys_ipc_hangup(int phoneid) … … 513 604 } 514 605 515 /** Wait for incoming ipc call or answer606 /** Wait for an incoming IPC call or an answer. 516 607 * 517 608 * @param calldata Pointer to buffer where the call/answer data is stored. … … 520 611 * for explanation. 521 612 * 522 * @return Callid, if callid & 1, then the call is answer 613 * @return Hash of the call. 614 * If IPC_CALLID_NOTIFICATION bit is set in the hash, the 615 * call is a notification. IPC_CALLID_ANSWERED denotes an 616 * answer. 523 617 */ 524 618 unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int flags) … … 542 636 ipc_call_free(call); 543 637 544 return ((unative_t) call) | IPC_CALLID_NOTIFICATION;638 return ((unative_t) call) | IPC_CALLID_NOTIFICATION; 545 639 } 546 640 … … 560 654 ipc_call_free(call); 561 655 562 return ((unative_t) call) | IPC_CALLID_ANSWERED;656 return ((unative_t) call) | IPC_CALLID_ANSWERED; 563 657 } 564 658 … … 574 668 } 575 669 576 /** Connect irq handler totask.577 * 578 * @param inr 579 * @param devno 580 * @param method 581 * @param ucode 582 * 583 * @return 670 /** Connect an IRQ handler to a task. 671 * 672 * @param inr IRQ number. 673 * @param devno Device number. 674 * @param method Method to be associated with the notification. 675 * @param ucode Uspace pointer to the top-half pseudocode. 676 * 677 * @return EPERM or a return code returned by ipc_irq_register(). 584 678 */ 585 679 unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method, … … 592 686 } 593 687 594 /** Disconnect irq handler from task. 595 * 596 * @param inr IRQ number. 597 * @param devno Device number. 688 /** Disconnect an IRQ handler from a task. 689 * 690 * @param inr IRQ number. 691 * @param devno Device number. 692 * 693 * @return Zero on success or EPERM on error.. 598 694 */ 599 695 unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno)
Note:
See TracChangeset
for help on using the changeset viewer.