HelenOS sources
This source file includes following definitions.
- irq_init
- irq_initialize
- irq_register
- irq_dispatch_and_lock_table
- irq_dispatch_and_lock
- irq_ht_hash
- irq_ht_key_hash
- irq_ht_equal
- irq_ht_key_equal
#include <ddi/irq.h>
#include <adt/hash.h>
#include <adt/hash_table.h>
#include <mm/slab.h>
#include <typedefs.h>
#include <synch/spinlock.h>
#include <console/console.h>
#include <interrupt.h>
#include <memw.h>
#include <arch.h>
slab_cache_t *irq_cache = NULL;
IRQ_SPINLOCK_STATIC_INITIALIZE(irq_kernel_hash_table_lock);
static hash_table_t irq_kernel_hash_table;
IRQ_SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
hash_table_t irq_uspace_hash_table;
static size_t irq_ht_hash(const ht_link_t *);
static size_t irq_ht_key_hash(const void *);
static bool irq_ht_equal(const ht_link_t *, const ht_link_t *);
static bool irq_ht_key_equal(const void *, const ht_link_t *);
static const hash_table_ops_t irq_ht_ops = {
.hash = irq_ht_hash,
.key_hash = irq_ht_key_hash,
.equal = irq_ht_equal,
.key_equal = irq_ht_key_equal
};
inr_t last_inr = 0;
void irq_init(size_t inrs, size_t chains)
{
last_inr = inrs - 1;
irq_cache = slab_cache_create("irq_t", sizeof(irq_t), 0, NULL, NULL,
FRAME_ATOMIC);
assert(irq_cache);
hash_table_create(&irq_uspace_hash_table, chains, 0, &irq_ht_ops);
hash_table_create(&irq_kernel_hash_table, chains, 0, &irq_ht_ops);
}
void irq_initialize(irq_t *irq)
{
memsetb(irq, sizeof(irq_t), 0);
irq_spinlock_initialize(&irq->lock, "irq.lock");
irq->inr = -1;
irq_initialize_arch(irq);
}
void irq_register(irq_t *irq)
{
irq_spinlock_lock(&irq_kernel_hash_table_lock, true);
irq_spinlock_lock(&irq->lock, false);
hash_table_insert(&irq_kernel_hash_table, &irq->link);
irq_spinlock_unlock(&irq->lock, false);
irq_spinlock_unlock(&irq_kernel_hash_table_lock, true);
}
static irq_t *
irq_dispatch_and_lock_table(hash_table_t *h, irq_spinlock_t *l, inr_t inr)
{
irq_spinlock_lock(l, false);
ht_link_t *first = hash_table_find(h, &inr);
for (ht_link_t *lnk = first; lnk;
lnk = hash_table_find_next(h, first, lnk)) {
irq_t *irq = hash_table_get_inst(lnk, irq_t, link);
irq_spinlock_lock(&irq->lock, false);
if (irq->claim(irq) == IRQ_ACCEPT) {
irq_spinlock_unlock(l, false);
return irq;
}
irq_spinlock_unlock(&irq->lock, false);
}
irq_spinlock_unlock(l, false);
return NULL;
}
irq_t *irq_dispatch_and_lock(inr_t inr)
{
if (console_override) {
irq_t *irq = irq_dispatch_and_lock_table(&irq_kernel_hash_table,
&irq_kernel_hash_table_lock, inr);
if (irq)
return irq;
return irq_dispatch_and_lock_table(&irq_uspace_hash_table,
&irq_uspace_hash_table_lock, inr);
}
irq_t *irq = irq_dispatch_and_lock_table(&irq_uspace_hash_table,
&irq_uspace_hash_table_lock, inr);
if (irq)
return irq;
return irq_dispatch_and_lock_table(&irq_kernel_hash_table,
&irq_kernel_hash_table_lock, inr);
}
size_t irq_ht_hash(const ht_link_t *item)
{
irq_t *irq = hash_table_get_inst(item, irq_t, link);
return hash_mix(irq->inr);
}
size_t irq_ht_key_hash(const void *key)
{
const inr_t *inr = key;
return hash_mix(*inr);
}
bool irq_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
{
irq_t *irq1 = hash_table_get_inst(item1, irq_t, link);
irq_t *irq2 = hash_table_get_inst(item2, irq_t, link);
return irq1->inr == irq2->inr;
}
bool irq_ht_key_equal(const void *key, const ht_link_t *item)
{
const inr_t *inr = key;
irq_t *irq = hash_table_get_inst(item, irq_t, link);
return irq->inr == *inr;
}
HelenOS homepage, sources at GitHub