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 |