Changeset 8b243f2 in mainline for kernel/generic/src/ipc/ipc.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/ipc.c
r4680ef5 r8b243f2 35 35 /* Lock ordering 36 36 * 37 * First the answerbox, then the phone 37 * First the answerbox, then the phone. 38 38 */ 39 39 … … 54 54 #include <ipc/irq.h> 55 55 56 /* Open channel that is assigned automatically to new tasks */56 /** Open channel that is assigned automatically to new tasks */ 57 57 answerbox_t *ipc_phone_0 = NULL; 58 58 59 59 static slab_cache_t *ipc_call_slab; 60 60 61 /* Initialize new call */ 61 /** Initialize a call structure. 62 * 63 * @param call Call structure to be initialized. 64 */ 62 65 static void _ipc_call_init(call_t *call) 63 66 { 64 memsetb((uintptr_t) call, sizeof(*call), 0);67 memsetb((uintptr_t) call, sizeof(*call), 0); 65 68 call->callerbox = &TASK->answerbox; 66 69 call->sender = TASK; 67 70 } 68 71 69 /** Allocate & initialize call structure72 /** Allocate and initialize a call structure. 70 73 * 71 * The call is initialized, so that the reply will be directed 72 * to TASK->answerbox 73 * 74 * @param flags Parameters for slab_alloc (ATOMIC, etc.) 75 */ 76 call_t * ipc_call_alloc(int flags) 74 * The call is initialized, so that the reply will be directed to 75 * TASK->answerbox. 76 * 77 * @param flags Parameters for slab_alloc (e.g FRAME_ATOMIC). 78 * 79 * @return If flags permit it, return NULL, or initialized kernel 80 * call structure. 81 */ 82 call_t *ipc_call_alloc(int flags) 77 83 { 78 84 call_t *call; … … 84 90 } 85 91 86 /** Initialize allocated call */ 92 /** Initialize a statically allocated call structure. 93 * 94 * @param call Statically allocated kernel call structure to be 95 * initialized. 96 */ 87 97 void ipc_call_static_init(call_t *call) 88 98 { … … 91 101 } 92 102 93 /** Deallocate call stracuture */ 103 /** Deallocate a call stracuture. 104 * 105 * @param call Call structure to be freed. 106 */ 94 107 void ipc_call_free(call_t *call) 95 108 { 109 ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); 96 110 slab_free(ipc_call_slab, call); 97 111 } 98 112 99 /** Initialize answerbox structure 113 /** Initialize an answerbox structure. 114 * 115 * @param box Answerbox structure to be initialized. 100 116 */ 101 117 void ipc_answerbox_init(answerbox_t *box) … … 113 129 } 114 130 115 /** Connect phone to answerbox */ 131 /** Connect a phone to an answerbox. 132 * 133 * @param phone Initialized phone structure. 134 * @param box Initialized answerbox structure. 135 */ 116 136 void ipc_phone_connect(phone_t *phone, answerbox_t *box) 117 137 { … … 128 148 } 129 149 130 /** Initialize phone structure and connect phone to answerbox 150 /** Initialize a phone structure. 151 * 152 * @param phone Phone structure to be initialized. 131 153 */ 132 154 void ipc_phone_init(phone_t *phone) … … 138 160 } 139 161 140 /** Helper function to facilitate synchronous calls */ 162 /** Helper function to facilitate synchronous calls. 163 * 164 * @param phone Destination kernel phone structure. 165 * @param request Call structure with request. 166 */ 141 167 void ipc_call_sync(phone_t *phone, call_t *request) 142 168 { … … 145 171 ipc_answerbox_init(&sync_box); 146 172 147 /* We will receive data on special box*/173 /* We will receive data in a special box. */ 148 174 request->callerbox = &sync_box; 149 175 … … 152 178 } 153 179 154 /** Answer message that was not dispatched and is not entered in 155 * any queue 180 /** Answer a message which was not dispatched and is not listed in any queue. 181 * 182 * @param call Call structure to be answered. 156 183 */ 157 184 static void _ipc_answer_free_call(call_t *call) … … 167 194 } 168 195 169 /** Answer message, that is in callee queue170 * 171 * @param box Answerbox that is answering the message172 * @param call Modified request that is being sent back196 /** Answer a message which is in a callee queue. 197 * 198 * @param box Answerbox that is answering the message. 199 * @param call Modified request that is being sent back. 173 200 */ 174 201 void ipc_answer(answerbox_t *box, call_t *call) … … 182 209 } 183 210 184 /** Simulate sending back a message 211 /** Simulate sending back a message. 185 212 * 186 213 * Most errors are better handled by forming a normal backward 187 214 * message and sending it as a normal answer. 215 * 216 * @param phone Phone structure the call should appear to come from. 217 * @param call Call structure to be answered. 218 * @param err Return value to be used for the answer. 188 219 */ 189 220 void ipc_backsend_err(phone_t *phone, call_t *call, unative_t err) … … 195 226 } 196 227 197 /* Unsafe unchecking ipc_call */ 228 /** Unsafe unchecking version of ipc_call. 229 * 230 * @param phone Phone structure the call comes from. 231 * @param box Destination answerbox structure. 232 */ 198 233 static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call) 199 234 { 200 if (! 235 if (!(call->flags & IPC_CALL_FORWARDED)) { 201 236 atomic_inc(&phone->active_calls); 202 237 call->data.phone = phone; … … 209 244 } 210 245 211 /** Send a asynchronous request using phone to answerbox 212 * 213 * @param phone Phone connected to answerbox. 214 * @param call Structure representing the call. 246 /** Send an asynchronous request using a phone to an answerbox. 247 * 248 * @param phone Phone structure the call comes from and which is 249 * connected to the destination answerbox. 250 * @param call Call structure with request. 251 * 252 * @return Return 0 on success, ENOENT on error. 215 253 */ 216 254 int ipc_call(phone_t *phone, call_t *call) … … 239 277 } 240 278 241 /** Disconnect phone from answerbox 242 * 243 * This call leaves the phone in HUNGUP state. The change to 'free' is done279 /** Disconnect phone from answerbox. 280 * 281 * This call leaves the phone in the HUNGUP state. The change to 'free' is done 244 282 * lazily later. 245 283 * 246 * @param phone Phone to be hung up284 * @param phone Phone structure to be hung up. 247 285 * 248 * @return 0 - phone disconnected, -1 - the phone was already disconnected 286 * @return Return 0 if the phone is disconnected. 287 * Return -1 if the phone was already disconnected. 249 288 */ 250 289 int ipc_phone_hangup(phone_t *phone) … … 254 293 255 294 spinlock_lock(&phone->lock); 256 if (phone->state == IPC_PHONE_FREE || phone->state == IPC_PHONE_HUNGUP \257 ||phone->state == IPC_PHONE_CONNECTING) {295 if (phone->state == IPC_PHONE_FREE || phone->state == IPC_PHONE_HUNGUP || 296 phone->state == IPC_PHONE_CONNECTING) { 258 297 spinlock_unlock(&phone->lock); 259 298 return -1; … … 280 319 } 281 320 282 /** Forwards call from one answerbox to a new one 283 * 284 * @param call Call to be redirected. 285 * @param newphone Phone to target answerbox. 286 * @param oldbox Old answerbox 287 * @return 0 on forward ok, error code, if there was error 321 /** Forwards call from one answerbox to another one. 322 * 323 * @param call Call structure to be redirected. 324 * @param newphone Phone structure to target answerbox. 325 * @param oldbox Old answerbox structure. 326 * 327 * @return Return 0 if forwarding succeeded or an error code if 328 * there was error. 288 329 * 289 * - the return value serves only as an information for the forwarder,290 * the original caller is notified automatically with EFORWARD330 * The return value serves only as an information for the forwarder, 331 * the original caller is notified automatically with EFORWARD. 291 332 */ 292 333 int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox) … … 300 341 301 342 302 /** Wait for phone call 303 * 304 * @param box Answerbox expecting the call. 305 * @param usec Timeout in microseconds. See documentation for waitq_sleep_timeout() for 306 * decription of its special meaning. 307 * @param flags Select mode of sleep operation. See documentation for waitq_sleep_timeout()i 308 * for description of its special meaning. 309 * @return Recived message address 310 * - to distinguish between call and answer, look at call->flags 311 */ 312 call_t * ipc_wait_for_call(answerbox_t *box, uint32_t usec, int flags) 343 /** Wait for a phone call. 344 * 345 * @param box Answerbox expecting the call. 346 * @param usec Timeout in microseconds. See documentation for 347 * waitq_sleep_timeout() for decription of its special 348 * meaning. 349 * @param flags Select mode of sleep operation. See documentation for 350 * waitq_sleep_timeout() for description of its special 351 * meaning. 352 * @return Recived call structure or NULL. 353 * 354 * To distinguish between a call and an answer, have a look at call->flags. 355 */ 356 call_t *ipc_wait_for_call(answerbox_t *box, uint32_t usec, int flags) 313 357 { 314 358 call_t *request; … … 351 395 } 352 396 353 /** Answer all calls from list with EHANGUP msg */ 397 /** Answer all calls from list with EHANGUP answer. 398 * 399 * @param lst Head of the list to be cleaned up. 400 */ 354 401 static void ipc_cleanup_call_list(link_t *lst) 355 402 { … … 365 412 } 366 413 367 /** Cleans up all IPC communication of the current task 414 /** Cleans up all IPC communication of the current task. 368 415 * 369 416 * Note: ipc_hangup sets returning answerbox to TASK->answerbox, you 370 * have to change it as well if you want to cleanup other current then current.417 * have to change it as well if you want to cleanup other tasks than TASK. 371 418 */ 372 419 void ipc_cleanup(void) … … 378 425 379 426 /* Disconnect all our phones ('ipc_phone_hangup') */ 380 for (i =0;i < IPC_MAX_PHONES; i++)427 for (i = 0; i < IPC_MAX_PHONES; i++) 381 428 ipc_phone_hangup(&TASK->phones[i]); 382 429 … … 414 461 /* Locking not needed, no one else should modify 415 462 * it, when we are in cleanup */ 416 for (i =0;i < IPC_MAX_PHONES; i++) {417 if (TASK->phones[i].state == IPC_PHONE_HUNGUP && \463 for (i = 0; i < IPC_MAX_PHONES; i++) { 464 if (TASK->phones[i].state == IPC_PHONE_HUNGUP && 418 465 atomic_get(&TASK->phones[i].active_calls) == 0) 419 466 TASK->phones[i].state = IPC_PHONE_FREE; … … 434 481 break; 435 482 436 call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); 437 ASSERT((call->flags & IPC_CALL_ANSWERED) || (call->flags & IPC_CALL_NOTIF)); 438 ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); 483 call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT, 484 SYNCH_FLAGS_NONE); 485 ASSERT((call->flags & IPC_CALL_ANSWERED) || 486 (call->flags & IPC_CALL_NOTIF)); 487 ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); 439 488 440 489 atomic_dec(&TASK->active_calls); … … 447 496 void ipc_init(void) 448 497 { 449 ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL, NULL, 0); 450 } 451 452 453 /** Kconsole - list answerbox contents */ 498 ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL, 499 NULL, 0); 500 } 501 502 503 /** List answerbox contents. 504 * 505 * @param taskid Task ID. 506 */ 454 507 void ipc_print_task(task_id_t taskid) 455 508 { … … 469 522 /* Print opened phones & details */ 470 523 printf("PHONE:\n"); 471 for (i =0; i < IPC_MAX_PHONES;i++) {524 for (i = 0; i < IPC_MAX_PHONES; i++) { 472 525 spinlock_lock(&task->phones[i].lock); 473 526 if (task->phones[i].state != IPC_PHONE_FREE) { 474 printf("%d: ", i);527 printf("%d: ", i); 475 528 switch (task->phones[i].state) { 476 529 case IPC_PHONE_CONNECTING:
Note:
See TracChangeset
for help on using the changeset viewer.