Changeset 162f919 in mainline for generic/src/ipc/ipc.c
- Timestamp:
- 2006-05-02T21:49:05Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cc35e88
- Parents:
- 281224a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/ipc/ipc.c
r281224a r162f919 45 45 #include <proc/thread.h> 46 46 #include <arch/interrupt.h> 47 #include <ipc/irq.h> 47 48 48 49 /* Open channel that is assigned automatically to new tasks */ … … 50 51 51 52 static slab_cache_t *ipc_call_slab; 52 53 typedef struct {54 SPINLOCK_DECLARE(lock);55 answerbox_t *box;56 } ipc_irq_t;57 58 static ipc_irq_t *irq_conns = NULL;59 static int irq_conns_size;60 53 61 54 /* Initialize new call */ … … 329 322 spinlock_lock(&box->irq_lock); 330 323 331 request = list_get_instance(box-> answers.next, call_t, list);324 request = list_get_instance(box->irq_notifs.next, call_t, list); 332 325 list_remove(&request->list); 333 326 … … 371 364 } 372 365 373 /** Disconnect all irq's notifications374 *375 * TODO: It may be better to do some linked list, so that376 * we wouldn't need to go through whole array every cleanup377 */378 static void ipc_irq_cleanup(answerbox_t *box)379 {380 int i;381 ipl_t ipl;382 383 for (i=0; i < irq_conns_size; i++) {384 ipl = interrupts_disable();385 spinlock_lock(&irq_conns[i].lock);386 if (irq_conns[i].box == box)387 irq_conns[i].box = NULL;388 spinlock_unlock(&irq_conns[i].lock);389 interrupts_restore(ipl);390 }391 }392 393 366 /** Cleans up all IPC communication of the given task 394 367 * … … 444 417 } 445 418 446 /** Initialize table of interrupt handlers */447 static void ipc_irq_make_table(int irqcount)448 {449 int i;450 451 irq_conns_size = irqcount;452 irq_conns = malloc(irqcount * (sizeof(*irq_conns)), 0);453 for (i=0; i < irqcount; i++) {454 spinlock_initialize(&irq_conns[i].lock, "irq_ipc_lock");455 irq_conns[i].box = NULL;456 }457 }458 459 void ipc_irq_unregister(answerbox_t *box, int irq)460 {461 ipl_t ipl;462 463 ipl = interrupts_disable();464 spinlock_lock(&irq_conns[irq].lock);465 if (irq_conns[irq].box == box)466 irq_conns[irq].box = NULL;467 468 spinlock_unlock(&irq_conns[irq].lock);469 interrupts_restore(ipl);470 }471 472 /** Register an answerbox as a receiving end of interrupts notifications */473 int ipc_irq_register(answerbox_t *box, int irq)474 {475 ipl_t ipl;476 477 ASSERT(irq_conns);478 479 ipl = interrupts_disable();480 spinlock_lock(&irq_conns[irq].lock);481 482 if (irq_conns[irq].box) {483 spinlock_unlock(&irq_conns[irq].lock);484 interrupts_restore(ipl);485 return EEXISTS;486 }487 irq_conns[irq].box = box;488 spinlock_unlock(&irq_conns[irq].lock);489 interrupts_restore(ipl);490 491 return 0;492 }493 494 /** Notify process that an irq had happend495 *496 * We expect interrupts to be disabled497 */498 void ipc_irq_send_notif(int irq)499 {500 call_t *call;501 502 ASSERT(irq_conns);503 spinlock_lock(&irq_conns[irq].lock);504 505 if (irq_conns[irq].box) {506 call = ipc_call_alloc(FRAME_ATOMIC);507 call->flags |= IPC_CALL_NOTIF;508 IPC_SET_METHOD(call->data, IPC_M_INTERRUPT);509 IPC_SET_ARG1(call->data, irq);510 511 spinlock_lock(&irq_conns[irq].box->irq_lock);512 list_append(&call->list, &irq_conns[irq].box->irq_notifs);513 spinlock_unlock(&irq_conns[irq].box->irq_lock);514 515 waitq_wakeup(&irq_conns[irq].box->wq, 0);516 }517 518 spinlock_unlock(&irq_conns[irq].lock);519 }520 419 521 420 /** Initilize ipc subsystem */
Note:
See TracChangeset
for help on using the changeset viewer.