Changes in kernel/generic/src/ddi/irq.c [d99c1d2:da1bafb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ddi/irq.c
rd99c1d2 rda1bafb 32 32 /** 33 33 * @file 34 * @brief 34 * @brief IRQ dispatcher. 35 35 * 36 36 * This file provides means of connecting IRQs with particular … … 78 78 #include <arch.h> 79 79 80 #define KEY_INR 81 #define KEY_DEVNO 82 83 /** 84 * 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 * 85 85 * This lock must be taken only when interrupts are disabled. 86 */ 87 SPINLOCK_INITIALIZE(irq_kernel_hash_table_lock); 86 * 87 */ 88 IRQ_SPINLOCK_STATIC_INITIALIZE(irq_kernel_hash_table_lock); 89 88 90 /** The kernel IRQ hash table. */ 89 91 static hash_table_t irq_kernel_hash_table; 90 92 91 /** 92 * Spinlock protecting the uspace IRQ hash table.93 /** Spinlock protecting the uspace IRQ hash table. 94 * 93 95 * This lock must be taken only when interrupts are disabled. 94 */ 95 SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock); 96 * 97 */ 98 IRQ_SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock); 99 96 100 /** The uspace IRQ hash table. */ 97 101 hash_table_t irq_uspace_hash_table; … … 100 104 * Hash table operations for cases when we know that 101 105 * there will be collisions between different keys. 106 * 102 107 */ 103 108 static size_t irq_ht_hash(unative_t *key); … … 116 121 * However, there might be still collisions among 117 122 * elements with single key (sharing of one IRQ). 123 * 118 124 */ 119 125 static size_t irq_lin_hash(unative_t *key); … … 132 138 /** Initialize IRQ subsystem. 133 139 * 134 * @param inrs Numbers of unique IRQ numbers or INRs.140 * @param inrs Numbers of unique IRQ numbers or INRs. 135 141 * @param chains Number of chains in the hash table. 142 * 136 143 */ 137 144 void irq_init(size_t inrs, size_t chains) … … 166 173 memsetb(irq, sizeof(irq_t), 0); 167 174 link_initialize(&irq->link); 168 spinlock_initialize(&irq->lock, "irq.lock");175 irq_spinlock_initialize(&irq->lock, "irq.lock"); 169 176 link_initialize(&irq->notif_cfg.link); 170 177 irq->inr = -1; 171 178 irq->devno = -1; 172 179 173 180 irq_initialize_arch(irq); 174 181 } … … 180 187 * function pointer and handler() function pointer. 181 188 * 182 * @param irq IRQ structure belonging to a device. 183 * @return True on success, false on failure. 189 * @param irq IRQ structure belonging to a device. 190 * 191 * @return True on success, false on failure. 192 * 184 193 */ 185 194 void irq_register(irq_t *irq) 186 195 { 187 ipl_t ipl;188 196 unative_t key[] = { 189 197 (unative_t) irq->inr, … … 191 199 }; 192 200 193 ipl = interrupts_disable(); 194 spinlock_lock(&irq_kernel_hash_table_lock); 195 spinlock_lock(&irq->lock); 201 irq_spinlock_lock(&irq_kernel_hash_table_lock, true); 202 irq_spinlock_lock(&irq->lock, false); 196 203 hash_table_insert(&irq_kernel_hash_table, key, &irq->link); 197 spinlock_unlock(&irq->lock); 198 spinlock_unlock(&irq_kernel_hash_table_lock); 199 interrupts_restore(ipl); 204 irq_spinlock_unlock(&irq->lock, false); 205 irq_spinlock_unlock(&irq_kernel_hash_table_lock, true); 200 206 } 201 207 … … 208 214 unative_t key[] = { 209 215 (unative_t) inr, 210 (unative_t) -1 /* search will use claim() instead of devno */216 (unative_t) -1 /* Search will use claim() instead of devno */ 211 217 }; 212 218 213 spinlock_lock(&irq_uspace_hash_table_lock);219 irq_spinlock_lock(&irq_uspace_hash_table_lock, false); 214 220 lnk = hash_table_find(&irq_uspace_hash_table, key); 215 221 if (lnk) { 216 irq_t *irq; 217 218 irq = hash_table_get_instance(lnk, irq_t, link); 219 spinlock_unlock(&irq_uspace_hash_table_lock); 222 irq_t *irq = hash_table_get_instance(lnk, irq_t, link); 223 irq_spinlock_unlock(&irq_uspace_hash_table_lock, false); 220 224 return irq; 221 225 } 222 spinlock_unlock(&irq_uspace_hash_table_lock);226 irq_spinlock_unlock(&irq_uspace_hash_table_lock, false); 223 227 224 228 return NULL; … … 233 237 unative_t key[] = { 234 238 (unative_t) inr, 235 (unative_t) -1 /* search will use claim() instead of devno */239 (unative_t) -1 /* Search will use claim() instead of devno */ 236 240 }; 237 241 238 spinlock_lock(&irq_kernel_hash_table_lock);242 irq_spinlock_lock(&irq_kernel_hash_table_lock, false); 239 243 lnk = hash_table_find(&irq_kernel_hash_table, key); 240 244 if (lnk) { 241 irq_t *irq; 242 243 irq = hash_table_get_instance(lnk, irq_t, link); 244 spinlock_unlock(&irq_kernel_hash_table_lock); 245 irq_t *irq = hash_table_get_instance(lnk, irq_t, link); 246 irq_spinlock_unlock(&irq_kernel_hash_table_lock, false); 245 247 return irq; 246 248 } 247 spinlock_unlock(&irq_kernel_hash_table_lock);249 irq_spinlock_unlock(&irq_kernel_hash_table_lock, false); 248 250 249 251 return NULL; … … 263 265 * 264 266 * @return IRQ structure of the respective device or NULL. 267 * 265 268 */ 266 269 irq_t *irq_dispatch_and_lock(inr_t inr) 267 270 { 268 irq_t *irq;269 270 271 /* 271 272 * If the kernel console is silenced, … … 277 278 */ 278 279 if (silent) { 279 irq = irq_dispatch_and_lock_uspace(inr);280 irq_t *irq = irq_dispatch_and_lock_uspace(inr); 280 281 if (irq) 281 282 return irq; 283 282 284 return irq_dispatch_and_lock_kernel(inr); 283 285 } 284 286 285 irq = irq_dispatch_and_lock_kernel(inr);287 irq_t *irq = irq_dispatch_and_lock_kernel(inr); 286 288 if (irq) 287 289 return irq; 290 288 291 return irq_dispatch_and_lock_uspace(inr); 289 292 } … … 301 304 * 302 305 * @return Index into the hash table. 306 * 303 307 */ 304 308 size_t irq_ht_hash(unative_t key[]) … … 322 326 * This function assumes interrupts are already disabled. 323 327 * 324 * @param key Keys (i.e. inr and devno).328 * @param key Keys (i.e. inr and devno). 325 329 * @param keys This is 2. 326 330 * @param item The item to compare the key with. 327 331 * 328 332 * @return True on match or false otherwise. 333 * 329 334 */ 330 335 bool irq_ht_compare(unative_t key[], size_t keys, link_t *item) … … 333 338 inr_t inr = (inr_t) key[KEY_INR]; 334 339 devno_t devno = (devno_t) key[KEY_DEVNO]; 335 340 336 341 bool rv; 337 342 338 spinlock_lock(&irq->lock);343 irq_spinlock_lock(&irq->lock, false); 339 344 if (devno == -1) { 340 345 /* Invoked by irq_dispatch_and_lock(). */ … … 348 353 /* unlock only on non-match */ 349 354 if (!rv) 350 spinlock_unlock(&irq->lock);351 355 irq_spinlock_unlock(&irq->lock, false); 356 352 357 return rv; 353 358 } … … 361 366 irq_t *irq __attribute__((unused)) 362 367 = hash_table_get_instance(lnk, irq_t, link); 363 spinlock_unlock(&irq->lock);368 irq_spinlock_unlock(&irq->lock, false); 364 369 } 365 370 … … 374 379 * 375 380 * @return Index into the hash table. 381 * 376 382 */ 377 383 size_t irq_lin_hash(unative_t key[]) … … 395 401 * This function assumes interrupts are already disabled. 396 402 * 397 * @param key Keys (i.e. inr and devno).403 * @param key Keys (i.e. inr and devno). 398 404 * @param keys This is 2. 399 405 * @param item The item to compare the key with. 400 406 * 401 407 * @return True on match or false otherwise. 408 * 402 409 */ 403 410 bool irq_lin_compare(unative_t key[], size_t keys, link_t *item) … … 407 414 bool rv; 408 415 409 spinlock_lock(&irq->lock);416 irq_spinlock_lock(&irq->lock, false); 410 417 if (devno == -1) { 411 418 /* Invoked by irq_dispatch_and_lock() */ … … 418 425 /* unlock only on non-match */ 419 426 if (!rv) 420 spinlock_unlock(&irq->lock);427 irq_spinlock_unlock(&irq->lock, false); 421 428 422 429 return rv; … … 425 432 /** Unlock IRQ structure after hash_table_remove(). 426 433 * 427 * @param lnk Link in the removed and locked IRQ structure. 434 * @param lnk Link in the removed and locked IRQ structure. 435 * 428 436 */ 429 437 void irq_lin_remove(link_t *lnk) … … 431 439 irq_t *irq __attribute__((unused)) 432 440 = hash_table_get_instance(lnk, irq_t, link); 433 spinlock_unlock(&irq->lock);441 irq_spinlock_unlock(&irq->lock, false); 434 442 } 435 443
Note:
See TracChangeset
for help on using the changeset viewer.