Subversion Repositories HelenOS

Rev

Rev 3950 | Rev 3968 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3950 Rev 3964
Line 70... Line 70...
70
#include <ddi/irq.h>
70
#include <ddi/irq.h>
71
#include <adt/hash_table.h>
71
#include <adt/hash_table.h>
72
#include <mm/slab.h>
72
#include <mm/slab.h>
73
#include <arch/types.h>
73
#include <arch/types.h>
74
#include <synch/spinlock.h>
74
#include <synch/spinlock.h>
-
 
75
#include <console/console.h>
75
#include <memstr.h>
76
#include <memstr.h>
76
#include <arch.h>
77
#include <arch.h>
77
 
78
 
78
#define KEY_INR     0
79
#define KEY_INR     0
79
#define KEY_DEVNO   1
80
#define KEY_DEVNO   1
Line 191... Line 192...
191
    spinlock_unlock(&irq->lock);   
192
    spinlock_unlock(&irq->lock);   
192
    spinlock_unlock(&irq_kernel_hash_table_lock);
193
    spinlock_unlock(&irq_kernel_hash_table_lock);
193
    interrupts_restore(ipl);
194
    interrupts_restore(ipl);
194
}
195
}
195
 
196
 
196
/** Dispatch the IRQ.
197
/** Search and lock the uspace IRQ hash table.
197
 *
198
 *
198
 * We assume this function is only called from interrupt
-
 
199
 * context (i.e. that interrupts are disabled prior to
-
 
200
 * this call).
-
 
201
 *
-
 
202
 * This function attempts to lookup a fitting IRQ
-
 
203
 * structure. In case of success, return with interrupts
-
 
204
 * disabled and holding the respective structure.
-
 
205
 *
-
 
206
 * @param inr Interrupt number (aka inr or irq).
-
 
207
 *
-
 
208
 * @return IRQ structure of the respective device or NULL.
-
 
209
 */
199
 */
210
irq_t *irq_dispatch_and_lock(inr_t inr)
200
static irq_t *irq_dispatch_and_lock_uspace(inr_t inr)
211
{
201
{
212
    link_t *lnk;
202
    link_t *lnk;
213
    unative_t key[] = {
203
    unative_t key[] = {
214
        (unative_t) inr,
204
        (unative_t) inr,
215
        (unative_t) -1      /* search will use claim() instead of devno */
205
        (unative_t) -1    /* search will use claim() instead of devno */
216
    };
206
    };
217
   
207
   
218
    /*
-
 
219
     * Try uspace handlers first.
-
 
220
     */
-
 
221
    spinlock_lock(&irq_uspace_hash_table_lock);
208
    spinlock_lock(&irq_uspace_hash_table_lock);
222
    lnk = hash_table_find(&irq_uspace_hash_table, key);
209
    lnk = hash_table_find(&irq_uspace_hash_table, key);
223
    if (lnk) {
210
    if (lnk) {
224
        irq_t *irq;
211
        irq_t *irq;
225
       
212
       
226
        irq = hash_table_get_instance(lnk, irq_t, link);
213
        irq = hash_table_get_instance(lnk, irq_t, link);
227
        spinlock_unlock(&irq_uspace_hash_table_lock);
214
        spinlock_unlock(&irq_uspace_hash_table_lock);
228
        return irq;
215
        return irq;
229
    }
216
    }
230
    spinlock_unlock(&irq_uspace_hash_table_lock);
217
    spinlock_unlock(&irq_uspace_hash_table_lock);
-
 
218
   
-
 
219
    return NULL;
-
 
220
}
231
 
221
 
-
 
222
/** Search and lock the kernel IRQ hash table.
232
    /*
223
 *
-
 
224
 */
-
 
225
static irq_t *irq_dispatch_and_lock_kernel(inr_t inr)
-
 
226
{
-
 
227
    link_t *lnk;
233
     * Fallback to kernel handlers.
228
    unative_t key[] = {
-
 
229
        (unative_t) inr,
-
 
230
        (unative_t) -1    /* search will use claim() instead of devno */
234
     */
231
    };
-
 
232
   
235
    spinlock_lock(&irq_kernel_hash_table_lock);
233
    spinlock_lock(&irq_kernel_hash_table_lock);
236
    lnk = hash_table_find(&irq_kernel_hash_table, key);
234
    lnk = hash_table_find(&irq_kernel_hash_table, key);
237
    if (lnk) {
235
    if (lnk) {
238
        irq_t *irq;
236
        irq_t *irq;
239
       
237
       
240
        irq = hash_table_get_instance(lnk, irq_t, link);
238
        irq = hash_table_get_instance(lnk, irq_t, link);
241
        spinlock_unlock(&irq_kernel_hash_table_lock);
239
        spinlock_unlock(&irq_kernel_hash_table_lock);
242
        return irq;
240
        return irq;
243
    }
241
    }
244
    spinlock_unlock(&irq_kernel_hash_table_lock);
242
    spinlock_unlock(&irq_kernel_hash_table_lock);
-
 
243
   
-
 
244
    return NULL;
-
 
245
}
245
 
246
 
-
 
247
/** Dispatch the IRQ.
-
 
248
 *
-
 
249
 * We assume this function is only called from interrupt
-
 
250
 * context (i.e. that interrupts are disabled prior to
-
 
251
 * this call).
-
 
252
 *
-
 
253
 * This function attempts to lookup a fitting IRQ
-
 
254
 * structure. In case of success, return with interrupts
-
 
255
 * disabled and holding the respective structure.
-
 
256
 *
-
 
257
 * @param inr Interrupt number (aka inr or irq).
-
 
258
 *
-
 
259
 * @return IRQ structure of the respective device or NULL.
-
 
260
 */
-
 
261
irq_t *irq_dispatch_and_lock(inr_t inr)
-
 
262
{
-
 
263
    irq_t *irq;
-
 
264
   
-
 
265
    /*
-
 
266
     * If the kernel console is silenced,
-
 
267
     * then try first the uspace handlers,
-
 
268
     * eventually fall back to kernel handlers.
-
 
269
     *
-
 
270
     * If the kernel console is active,
-
 
271
     * then do it the other way around.
-
 
272
     */
-
 
273
    if (silent) {
-
 
274
        irq = irq_dispatch_and_lock_uspace(inr);
-
 
275
        if (irq)
-
 
276
            return irq;
-
 
277
        return irq_dispatch_and_lock_kernel(inr);
-
 
278
    }
-
 
279
   
-
 
280
    irq = irq_dispatch_and_lock_kernel(inr);
-
 
281
    if (irq)
246
    return NULL;   
282
        return irq;
-
 
283
    return irq_dispatch_and_lock_uspace(inr);
247
}
284
}
248
 
285
 
249
/** Compute hash index for the key.
286
/** Compute hash index for the key.
250
 *
287
 *
251
 * This function computes hash index into
288
 * This function computes hash index into