Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ddi/irq.c

    r98000fb r78ffb70  
    3232/**
    3333 * @file
    34  * @brief       IRQ dispatcher.
     34 * @brief IRQ dispatcher.
    3535 *
    3636 * This file provides means of connecting IRQs with particular
     
    7171#include <adt/hash_table.h>
    7272#include <mm/slab.h>
    73 #include <arch/types.h>
     73#include <typedefs.h>
    7474#include <synch/spinlock.h>
    7575#include <console/console.h>
     76#include <interrupt.h>
    7677#include <memstr.h>
    7778#include <arch.h>
    7879
    79 #define KEY_INR         0
    80 #define KEY_DEVNO       1
    81 
    82 /**
    83  * Spinlock protecting the kernel IRQ hash table.
     80#define KEY_INR    0
     81#define KEY_DEVNO  1
     82
     83/** Spinlock protecting the kernel IRQ hash table.
     84 *
    8485 * This lock must be taken only when interrupts are disabled.
    85  */
    86 SPINLOCK_INITIALIZE(irq_kernel_hash_table_lock);
     86 *
     87 */
     88IRQ_SPINLOCK_STATIC_INITIALIZE(irq_kernel_hash_table_lock);
     89
    8790/** The kernel IRQ hash table. */
    8891static hash_table_t irq_kernel_hash_table;
    8992
    90 /**
    91  * Spinlock protecting the uspace IRQ hash table.
     93/** Spinlock protecting the uspace IRQ hash table.
     94 *
    9295 * This lock must be taken only when interrupts are disabled.
    93  */
    94 SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
     96 *
     97 */
     98IRQ_SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
     99
    95100/** The uspace IRQ hash table. */
    96101hash_table_t irq_uspace_hash_table;
     
    99104 * Hash table operations for cases when we know that
    100105 * there will be collisions between different keys.
    101  */
    102 static size_t irq_ht_hash(unative_t *key);
    103 static bool irq_ht_compare(unative_t *key, size_t keys, link_t *item);
     106 *
     107 */
     108static size_t irq_ht_hash(sysarg_t *key);
     109static bool irq_ht_compare(sysarg_t *key, size_t keys, link_t *item);
    104110static void irq_ht_remove(link_t *item);
    105111
     
    115121 * However, there might be still collisions among
    116122 * elements with single key (sharing of one IRQ).
    117  */
    118 static size_t irq_lin_hash(unative_t *key);
    119 static bool irq_lin_compare(unative_t *key, size_t keys, link_t *item);
     123 *
     124 */
     125static size_t irq_lin_hash(sysarg_t *key);
     126static bool irq_lin_compare(sysarg_t *key, size_t keys, link_t *item);
    120127static void irq_lin_remove(link_t *item);
    121128
     
    129136static size_t buckets;
    130137
     138/** Last valid INR. */
     139inr_t last_inr = 0;
     140
    131141/** Initialize IRQ subsystem.
    132142 *
    133  * @param inrs Numbers of unique IRQ numbers or INRs.
     143 * @param inrs   Numbers of unique IRQ numbers or INRs.
    134144 * @param chains Number of chains in the hash table.
     145 *
    135146 */
    136147void irq_init(size_t inrs, size_t chains)
    137148{
    138149        buckets = chains;
     150        last_inr = inrs - 1;
     151
    139152        /*
    140153         * Be smart about the choice of the hash table operations.
     
    165178        memsetb(irq, sizeof(irq_t), 0);
    166179        link_initialize(&irq->link);
    167         spinlock_initialize(&irq->lock, "irq.lock");
     180        irq_spinlock_initialize(&irq->lock, "irq.lock");
    168181        link_initialize(&irq->notif_cfg.link);
    169182        irq->inr = -1;
    170183        irq->devno = -1;
     184       
     185        irq_initialize_arch(irq);
    171186}
    172187
     
    177192 * function pointer and handler() function pointer.
    178193 *
    179  * @param irq           IRQ structure belonging to a device.
    180  * @return              True on success, false on failure.
     194 * @param irq IRQ structure belonging to a device.
     195 *
     196 * @return True on success, false on failure.
     197 *
    181198 */
    182199void irq_register(irq_t *irq)
    183200{
    184         ipl_t ipl;
    185         unative_t key[] = {
    186                 (unative_t) irq->inr,
    187                 (unative_t) irq->devno
     201        sysarg_t key[] = {
     202                (sysarg_t) irq->inr,
     203                (sysarg_t) irq->devno
    188204        };
    189205       
    190         ipl = interrupts_disable();
    191         spinlock_lock(&irq_kernel_hash_table_lock);
    192         spinlock_lock(&irq->lock);
     206        irq_spinlock_lock(&irq_kernel_hash_table_lock, true);
     207        irq_spinlock_lock(&irq->lock, false);
    193208        hash_table_insert(&irq_kernel_hash_table, key, &irq->link);
    194         spinlock_unlock(&irq->lock);   
    195         spinlock_unlock(&irq_kernel_hash_table_lock);
    196         interrupts_restore(ipl);
     209        irq_spinlock_unlock(&irq->lock, false);
     210        irq_spinlock_unlock(&irq_kernel_hash_table_lock, true);
    197211}
    198212
     
    203217{
    204218        link_t *lnk;
    205         unative_t key[] = {
    206                 (unative_t) inr,
    207                 (unative_t) -1    /* search will use claim() instead of devno */
     219        sysarg_t key[] = {
     220                (sysarg_t) inr,
     221                (sysarg_t) -1    /* Search will use claim() instead of devno */
    208222        };
    209223       
    210         spinlock_lock(&irq_uspace_hash_table_lock);
     224        irq_spinlock_lock(&irq_uspace_hash_table_lock, false);
    211225        lnk = hash_table_find(&irq_uspace_hash_table, key);
    212226        if (lnk) {
    213                 irq_t *irq;
    214                
    215                 irq = hash_table_get_instance(lnk, irq_t, link);
    216                 spinlock_unlock(&irq_uspace_hash_table_lock);
     227                irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
     228                irq_spinlock_unlock(&irq_uspace_hash_table_lock, false);
    217229                return irq;
    218230        }
    219         spinlock_unlock(&irq_uspace_hash_table_lock);
     231        irq_spinlock_unlock(&irq_uspace_hash_table_lock, false);
    220232       
    221233        return NULL;
     
    228240{
    229241        link_t *lnk;
    230         unative_t key[] = {
    231                 (unative_t) inr,
    232                 (unative_t) -1    /* search will use claim() instead of devno */
     242        sysarg_t key[] = {
     243                (sysarg_t) inr,
     244                (sysarg_t) -1    /* Search will use claim() instead of devno */
    233245        };
    234246       
    235         spinlock_lock(&irq_kernel_hash_table_lock);
     247        irq_spinlock_lock(&irq_kernel_hash_table_lock, false);
    236248        lnk = hash_table_find(&irq_kernel_hash_table, key);
    237249        if (lnk) {
    238                 irq_t *irq;
    239                
    240                 irq = hash_table_get_instance(lnk, irq_t, link);
    241                 spinlock_unlock(&irq_kernel_hash_table_lock);
     250                irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
     251                irq_spinlock_unlock(&irq_kernel_hash_table_lock, false);
    242252                return irq;
    243253        }
    244         spinlock_unlock(&irq_kernel_hash_table_lock);
     254        irq_spinlock_unlock(&irq_kernel_hash_table_lock, false);
    245255       
    246256        return NULL;
     
    260270 *
    261271 * @return IRQ structure of the respective device or NULL.
     272 *
    262273 */
    263274irq_t *irq_dispatch_and_lock(inr_t inr)
    264275{
    265         irq_t *irq;
    266        
    267276        /*
    268277         * If the kernel console is silenced,
     
    274283         */
    275284        if (silent) {
    276                 irq = irq_dispatch_and_lock_uspace(inr);
     285                irq_t *irq = irq_dispatch_and_lock_uspace(inr);
    277286                if (irq)
    278287                        return irq;
     288               
    279289                return irq_dispatch_and_lock_kernel(inr);
    280290        }
    281291       
    282         irq = irq_dispatch_and_lock_kernel(inr);
     292        irq_t *irq = irq_dispatch_and_lock_kernel(inr);
    283293        if (irq)
    284294                return irq;
     295       
    285296        return irq_dispatch_and_lock_uspace(inr);
    286297}
     
    298309 *
    299310 * @return Index into the hash table.
    300  */
    301 size_t irq_ht_hash(unative_t key[])
     311 *
     312 */
     313size_t irq_ht_hash(sysarg_t key[])
    302314{
    303315        inr_t inr = (inr_t) key[KEY_INR];
     
    319331 * This function assumes interrupts are already disabled.
    320332 *
    321  * @param key Keys (i.e. inr and devno).
     333 * @param key  Keys (i.e. inr and devno).
    322334 * @param keys This is 2.
    323335 * @param item The item to compare the key with.
    324336 *
    325337 * @return True on match or false otherwise.
    326  */
    327 bool irq_ht_compare(unative_t key[], size_t keys, link_t *item)
     338 *
     339 */
     340bool irq_ht_compare(sysarg_t key[], size_t keys, link_t *item)
    328341{
    329342        irq_t *irq = hash_table_get_instance(item, irq_t, link);
    330343        inr_t inr = (inr_t) key[KEY_INR];
    331344        devno_t devno = (devno_t) key[KEY_DEVNO];
    332 
     345       
    333346        bool rv;
    334347       
    335         spinlock_lock(&irq->lock);
     348        irq_spinlock_lock(&irq->lock, false);
    336349        if (devno == -1) {
    337350                /* Invoked by irq_dispatch_and_lock(). */
     
    345358        /* unlock only on non-match */
    346359        if (!rv)
    347                 spinlock_unlock(&irq->lock);
    348 
     360                irq_spinlock_unlock(&irq->lock, false);
     361       
    349362        return rv;
    350363}
     
    358371        irq_t *irq __attribute__((unused))
    359372            = hash_table_get_instance(lnk, irq_t, link);
    360         spinlock_unlock(&irq->lock);
     373        irq_spinlock_unlock(&irq->lock, false);
    361374}
    362375
     
    371384 *
    372385 * @return Index into the hash table.
    373  */
    374 size_t irq_lin_hash(unative_t key[])
     386 *
     387 */
     388size_t irq_lin_hash(sysarg_t key[])
    375389{
    376390        inr_t inr = (inr_t) key[KEY_INR];
     
    392406 * This function assumes interrupts are already disabled.
    393407 *
    394  * @param key Keys (i.e. inr and devno).
     408 * @param key  Keys (i.e. inr and devno).
    395409 * @param keys This is 2.
    396410 * @param item The item to compare the key with.
    397411 *
    398412 * @return True on match or false otherwise.
    399  */
    400 bool irq_lin_compare(unative_t key[], size_t keys, link_t *item)
     413 *
     414 */
     415bool irq_lin_compare(sysarg_t key[], size_t keys, link_t *item)
    401416{
    402417        irq_t *irq = list_get_instance(item, irq_t, link);
     
    404419        bool rv;
    405420       
    406         spinlock_lock(&irq->lock);
     421        irq_spinlock_lock(&irq->lock, false);
    407422        if (devno == -1) {
    408423                /* Invoked by irq_dispatch_and_lock() */
     
    415430        /* unlock only on non-match */
    416431        if (!rv)
    417                 spinlock_unlock(&irq->lock);
     432                irq_spinlock_unlock(&irq->lock, false);
    418433       
    419434        return rv;
     
    422437/** Unlock IRQ structure after hash_table_remove().
    423438 *
    424  * @param lnk           Link in the removed and locked IRQ structure.
     439 * @param lnk Link in the removed and locked IRQ structure.
     440 *
    425441 */
    426442void irq_lin_remove(link_t *lnk)
     
    428444        irq_t *irq __attribute__((unused))
    429445            = hash_table_get_instance(lnk, irq_t, link);
    430         spinlock_unlock(&irq->lock);
     446        irq_spinlock_unlock(&irq->lock, false);
    431447}
    432448
Note: See TracChangeset for help on using the changeset viewer.