Changeset e9d15d9 in mainline for kernel/generic
- Timestamp:
- 2017-08-18T21:15:26Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 24abb85d
- Parents:
- 1c85bae
- Location:
- kernel/generic
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/irq.h
r1c85bae re9d15d9 53 53 extern void ipc_irq_top_half_handler(irq_t *); 54 54 55 extern int ipc_irq_unsubscribe(answerbox_t *, in r_t, devno_t);55 extern int ipc_irq_unsubscribe(answerbox_t *, int); 56 56 extern void ipc_irq_cleanup(answerbox_t *); 57 57 -
kernel/generic/include/ipc/sysipc.h
r1c85bae re9d15d9 57 57 58 58 extern sysarg_t sys_ipc_irq_subscribe(inr_t, devno_t, sysarg_t, irq_code_t *); 59 extern sysarg_t sys_ipc_irq_unsubscribe( inr_t, devno_t);59 extern sysarg_t sys_ipc_irq_unsubscribe(sysarg_t); 60 60 61 61 #ifdef __32_BITS__ -
kernel/generic/include/kobject/kobject.h
r1c85bae re9d15d9 38 38 #include <typedefs.h> 39 39 #include <ipc/ipc.h> 40 #include <ddi/irq.h> 40 41 41 42 #define MAX_KERNEL_OBJECTS 64 42 43 #define KOBJECT_INVALID_CAP -144 43 45 44 typedef enum { 46 45 KOBJECT_TYPE_INVALID, 47 46 KOBJECT_TYPE_ALLOCATED, 48 KOBJECT_TYPE_PHONE 47 KOBJECT_TYPE_PHONE, 48 KOBJECT_TYPE_IRQ 49 49 } kobject_type_t; 50 50 … … 55 55 union { 56 56 phone_t phone; 57 irq_t irq; 57 58 }; 58 59 } kobject_t; … … 60 61 struct task; 61 62 62 extern void kobject_init (kobject_t *);63 extern void kobject_initialize(kobject_t *); 63 64 extern kobject_t *kobject_get(struct task *, int, kobject_type_t); 64 65 extern kobject_t *kobject_get_current(int, kobject_type_t); -
kernel/generic/include/proc/task.h
r1c85bae re9d15d9 37 37 38 38 #include <cpu.h> 39 #include <kobject/kobject.h>40 39 #include <ipc/ipc.h> 41 40 #include <ipc/event.h> … … 66 65 67 66 struct thread; 67 struct kobject; 68 68 69 69 /** Task structure. */ … … 98 98 99 99 /** Kernel objects */ 100 kobject_t kobject[MAX_KERNEL_OBJECTS];100 struct kobject *kobject; 101 101 102 102 /* IPC stuff */ -
kernel/generic/src/ipc/ipc.c
r1c85bae re9d15d9 59 59 #include <arch/interrupt.h> 60 60 #include <ipc/irq.h> 61 #include <kobject/kobject.h> 61 62 62 63 static void ipc_forget_call(call_t *); -
kernel/generic/src/ipc/ipcrsc.c
r1c85bae re9d15d9 133 133 #include <assert.h> 134 134 #include <abi/errno.h> 135 #include <kobject/kobject.h> 135 136 136 137 /** Find call_t * in call table according to callid. … … 198 199 * 199 200 * @return New phone capability. 200 * @return KOBJECT_INVALID_CAPif a new capability cannot be allocated.201 * @return Negative error code if a new capability cannot be allocated. 201 202 */ 202 203 int phone_alloc(task_t *task) 203 204 { 204 205 int cap = kobject_alloc(task); 205 if (cap != KOBJECT_INVALID_CAP) {206 if (cap >= 0) { 206 207 irq_spinlock_lock(&task->lock, true); 207 208 kobject_t *kobj = &task->kobject[cap]; -
kernel/generic/src/ipc/irq.c
r1c85bae re9d15d9 84 84 #include <print.h> 85 85 #include <macros.h> 86 #include <kobject/kobject.h> 86 87 87 88 static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount) … … 298 299 * @param ucode Uspace pointer to top-half pseudocode. 299 300 * 300 * @return EOK on success or a negative error code. 301 * @return IRQ capability. 302 * @return Negative error code. 301 303 * 302 304 */ … … 321 323 322 324 /* 323 * Allocate and populate the IRQ structure.325 * Allocate and populate the IRQ kernel object. 324 326 */ 325 irq_t *irq = malloc(sizeof(irq_t), 0); 326 327 int cap = kobject_alloc(TASK); 328 if (cap < 0) 329 return cap; 330 kobject_t *kobj = kobject_get_current(cap, KOBJECT_TYPE_ALLOCATED); 331 assert(kobj); 332 kobj->type = KOBJECT_TYPE_IRQ; 333 334 irq_t *irq = &kobj->irq; 327 335 irq_initialize(irq); 328 336 irq->devno = devno; … … 351 359 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true); 352 360 353 free(irq);361 kobject_free(TASK, cap); 354 362 return EEXIST; 355 363 } … … 366 374 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true); 367 375 368 return EOK;376 return cap; 369 377 } 370 378 371 379 /** Unsubscribe task from IRQ notification. 372 380 * 373 * @param box Answerbox associated with the notification. 374 * @param inr IRQ number. 375 * @param devno Device number. 381 * @param box Answerbox associated with the notification. 382 * @param irq_cap IRQ capability. 376 383 * 377 384 * @return EOK on success or a negative error code. 378 385 * 379 386 */ 380 int ipc_irq_unsubscribe(answerbox_t *box, inr_t inr, devno_t devno) 381 { 382 sysarg_t key[] = { 383 (sysarg_t) inr, 384 (sysarg_t) devno 385 }; 386 387 if ((inr < 0) || (inr > last_inr)) 388 return ELIMIT; 389 387 int ipc_irq_unsubscribe(answerbox_t *box, int irq_cap) 388 { 389 kobject_t *kobj = kobject_get_current(irq_cap, KOBJECT_TYPE_IRQ); 390 if (!kobj) 391 return ENOENT; 392 irq_t *irq = &kobj->irq; 393 390 394 irq_spinlock_lock(&irq_uspace_hash_table_lock, true); 391 link_t *lnk = hash_table_find(&irq_uspace_hash_table, key); 392 if (!lnk) { 393 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true); 394 return ENOENT; 395 } 396 397 irq_t *irq = hash_table_get_instance(lnk, irq_t, link); 398 399 /* irq is locked */ 395 irq_spinlock_lock(&irq->lock, false); 400 396 irq_spinlock_lock(&box->irq_lock, false); 401 397 … … 405 401 list_remove(&irq->notif_cfg.link); 406 402 407 /*408 * We need to drop the IRQ lock now because hash_table_remove() will try409 * to reacquire it. That basically violates the natural locking order,410 * but a deadlock in hash_table_remove() is prevented by the fact that411 * we already held the IRQ lock and didn't drop the hash table lock in412 * the meantime.413 */414 irq_spinlock_unlock(&irq->lock, false);415 416 403 /* Remove the IRQ from the uspace IRQ hash table. */ 417 hash_table_remove (&irq_uspace_hash_table, key, 2);404 hash_table_remove_item(&irq_uspace_hash_table, &irq->link); 418 405 419 406 irq_spinlock_unlock(&box->irq_lock, false); 407 /* irq->lock unlocked by the hash table remove_callback */ 420 408 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true); 421 409 … … 423 411 code_free(irq->notif_cfg.code); 424 412 425 /* Free up the IRQ structure. */426 free(irq);413 /* Free up the IRQ kernel object. */ 414 kobject_free(TASK, irq_cap); 427 415 428 416 return EOK; … … 431 419 /** Disconnect all IRQ notifications from an answerbox. 432 420 * 433 * This function is effective because the answerbox contains 434 * list of all irq_t structures that are subscribed to 435 * send notifications to it. 421 * This function is effective because the answerbox contains list of all irq_t 422 * structures that are subscribed to send notifications to it. 436 423 * 437 424 * @param box Answerbox for which we want to carry out the cleanup. … … 460 447 } 461 448 462 sysarg_t key[2];463 key[0] = irq->inr;464 key[1] = irq->devno;465 466 449 assert(irq->notif_cfg.answerbox == box); 467 450 … … 469 452 list_remove(&irq->notif_cfg.link); 470 453 471 /*472 * We need to drop the IRQ lock now because hash_table_remove()473 * will try to reacquire it. That basically violates the natural474 * locking order, but a deadlock in hash_table_remove() is475 * prevented by the fact that we already held the IRQ lock and476 * didn't drop the hash table lock in the meantime.477 */478 irq_spinlock_unlock(&irq->lock, false);479 480 454 /* Remove from the hash table. */ 481 hash_table_remove (&irq_uspace_hash_table, key, 2);455 hash_table_remove_item(&irq_uspace_hash_table, &irq->link); 482 456 483 457 /* … … 488 462 489 463 code_free(irq->notif_cfg.code); 490 free(irq); 464 465 // XXX: what to do about the irq capability? The task is in 466 // clean-up anyway. 491 467 492 468 /* Reacquire both locks before taking another round. */ -
kernel/generic/src/ipc/sysipc.c
r1c85bae re9d15d9 805 805 * @param ucode Uspace pointer to the top-half pseudocode. 806 806 * 807 * @return EPERM or a return code returned by ipc_irq_subscribe(). 807 * @return IRQ kernel object capability 808 * @return EPERM 809 * @return Error code returned by ipc_irq_subscribe(). 808 810 * 809 811 */ … … 825 827 * 826 828 */ 827 sysarg_t sys_ipc_irq_unsubscribe( inr_t inr, devno_t devno)829 sysarg_t sys_ipc_irq_unsubscribe(sysarg_t cap) 828 830 { 829 831 if (!(perm_get(TASK) & PERM_IRQ_REG)) 830 832 return EPERM; 831 833 832 ipc_irq_unsubscribe(&TASK->answerbox, inr, devno);834 ipc_irq_unsubscribe(&TASK->answerbox, cap); 833 835 834 836 return 0; -
kernel/generic/src/kobject/kobject.c
r1c85bae re9d15d9 36 36 #include <proc/task.h> 37 37 #include <synch/spinlock.h> 38 #include <abi/errno.h> 38 39 39 void kobject_init (kobject_t *kobj)40 void kobject_initialize(kobject_t *kobj) 40 41 { 41 42 kobj->type = KOBJECT_TYPE_INVALID; … … 66 67 if (kobj->type > KOBJECT_TYPE_ALLOCATED) { 67 68 if (kobj->can_reclaim && kobj->can_reclaim(kobj)) 68 kobject_init (kobj);69 kobject_initialize(kobj); 69 70 } 70 71 if (kobj->type == KOBJECT_TYPE_INVALID) { … … 76 77 irq_spinlock_unlock(&task->lock, true); 77 78 78 return KOBJECT_INVALID_CAP;79 return ELIMIT; 79 80 } 80 81 … … 86 87 87 88 irq_spinlock_lock(&task->lock, true); 88 kobject_init (&task->kobject[cap]);89 kobject_initialize(&task->kobject[cap]); 89 90 irq_spinlock_unlock(&task->lock, true); 90 91 } -
kernel/generic/src/proc/task.c
r1c85bae re9d15d9 50 50 #include <adt/btree.h> 51 51 #include <adt/list.h> 52 #include <kobject/kobject.h> 52 53 #include <ipc/ipc.h> 53 54 #include <ipc/ipcrsc.h> … … 166 167 167 168 list_initialize(&task->threads); 168 169 int cap; 170 for (cap = 0; cap < MAX_KERNEL_OBJECTS; cap++) 171 kobject_init(&task->kobject[cap]); 169 170 task->kobject = malloc(sizeof(kobject_t) * MAX_KERNEL_OBJECTS, 0); 172 171 173 172 ipc_answerbox_init(&task->answerbox, task); … … 206 205 task->ucycles = 0; 207 206 task->kcycles = 0; 207 208 int cap; 209 for (cap = 0; cap < MAX_KERNEL_OBJECTS; cap++) 210 kobject_initialize(&task->kobject[cap]); 208 211 209 212 task->ipc_info.call_sent = 0; … … 282 285 as_release(task->as); 283 286 287 free(task->kobject); 288 284 289 slab_free(task_slab, task); 285 290 }
Note:
See TracChangeset
for help on using the changeset viewer.