Changes in kernel/generic/src/ddi/irq.c [98000fb:78ffb70] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ddi/irq.c
r98000fb r78ffb70 32 32 /** 33 33 * @file 34 * @brief 34 * @brief IRQ dispatcher. 35 35 * 36 36 * This file provides means of connecting IRQs with particular … … 71 71 #include <adt/hash_table.h> 72 72 #include <mm/slab.h> 73 #include < arch/types.h>73 #include <typedefs.h> 74 74 #include <synch/spinlock.h> 75 75 #include <console/console.h> 76 #include <interrupt.h> 76 77 #include <memstr.h> 77 78 #include <arch.h> 78 79 79 #define KEY_INR 80 #define KEY_DEVNO 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 * 84 85 * This lock must be taken only when interrupts are disabled. 85 */ 86 SPINLOCK_INITIALIZE(irq_kernel_hash_table_lock); 86 * 87 */ 88 IRQ_SPINLOCK_STATIC_INITIALIZE(irq_kernel_hash_table_lock); 89 87 90 /** The kernel IRQ hash table. */ 88 91 static hash_table_t irq_kernel_hash_table; 89 92 90 /** 91 * Spinlock protecting the uspace IRQ hash table.93 /** Spinlock protecting the uspace IRQ hash table. 94 * 92 95 * This lock must be taken only when interrupts are disabled. 93 */ 94 SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock); 96 * 97 */ 98 IRQ_SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock); 99 95 100 /** The uspace IRQ hash table. */ 96 101 hash_table_t irq_uspace_hash_table; … … 99 104 * Hash table operations for cases when we know that 100 105 * 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 */ 108 static size_t irq_ht_hash(sysarg_t *key); 109 static bool irq_ht_compare(sysarg_t *key, size_t keys, link_t *item); 104 110 static void irq_ht_remove(link_t *item); 105 111 … … 115 121 * However, there might be still collisions among 116 122 * 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 */ 125 static size_t irq_lin_hash(sysarg_t *key); 126 static bool irq_lin_compare(sysarg_t *key, size_t keys, link_t *item); 120 127 static void irq_lin_remove(link_t *item); 121 128 … … 129 136 static size_t buckets; 130 137 138 /** Last valid INR. */ 139 inr_t last_inr = 0; 140 131 141 /** Initialize IRQ subsystem. 132 142 * 133 * @param inrs Numbers of unique IRQ numbers or INRs.143 * @param inrs Numbers of unique IRQ numbers or INRs. 134 144 * @param chains Number of chains in the hash table. 145 * 135 146 */ 136 147 void irq_init(size_t inrs, size_t chains) 137 148 { 138 149 buckets = chains; 150 last_inr = inrs - 1; 151 139 152 /* 140 153 * Be smart about the choice of the hash table operations. … … 165 178 memsetb(irq, sizeof(irq_t), 0); 166 179 link_initialize(&irq->link); 167 spinlock_initialize(&irq->lock, "irq.lock");180 irq_spinlock_initialize(&irq->lock, "irq.lock"); 168 181 link_initialize(&irq->notif_cfg.link); 169 182 irq->inr = -1; 170 183 irq->devno = -1; 184 185 irq_initialize_arch(irq); 171 186 } 172 187 … … 177 192 * function pointer and handler() function pointer. 178 193 * 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 * 181 198 */ 182 199 void irq_register(irq_t *irq) 183 200 { 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 188 204 }; 189 205 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); 193 208 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); 197 211 } 198 212 … … 203 217 { 204 218 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 */ 208 222 }; 209 223 210 spinlock_lock(&irq_uspace_hash_table_lock);224 irq_spinlock_lock(&irq_uspace_hash_table_lock, false); 211 225 lnk = hash_table_find(&irq_uspace_hash_table, key); 212 226 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); 217 229 return irq; 218 230 } 219 spinlock_unlock(&irq_uspace_hash_table_lock);231 irq_spinlock_unlock(&irq_uspace_hash_table_lock, false); 220 232 221 233 return NULL; … … 228 240 { 229 241 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 */ 233 245 }; 234 246 235 spinlock_lock(&irq_kernel_hash_table_lock);247 irq_spinlock_lock(&irq_kernel_hash_table_lock, false); 236 248 lnk = hash_table_find(&irq_kernel_hash_table, key); 237 249 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); 242 252 return irq; 243 253 } 244 spinlock_unlock(&irq_kernel_hash_table_lock);254 irq_spinlock_unlock(&irq_kernel_hash_table_lock, false); 245 255 246 256 return NULL; … … 260 270 * 261 271 * @return IRQ structure of the respective device or NULL. 272 * 262 273 */ 263 274 irq_t *irq_dispatch_and_lock(inr_t inr) 264 275 { 265 irq_t *irq;266 267 276 /* 268 277 * If the kernel console is silenced, … … 274 283 */ 275 284 if (silent) { 276 irq = irq_dispatch_and_lock_uspace(inr);285 irq_t *irq = irq_dispatch_and_lock_uspace(inr); 277 286 if (irq) 278 287 return irq; 288 279 289 return irq_dispatch_and_lock_kernel(inr); 280 290 } 281 291 282 irq = irq_dispatch_and_lock_kernel(inr);292 irq_t *irq = irq_dispatch_and_lock_kernel(inr); 283 293 if (irq) 284 294 return irq; 295 285 296 return irq_dispatch_and_lock_uspace(inr); 286 297 } … … 298 309 * 299 310 * @return Index into the hash table. 300 */ 301 size_t irq_ht_hash(unative_t key[]) 311 * 312 */ 313 size_t irq_ht_hash(sysarg_t key[]) 302 314 { 303 315 inr_t inr = (inr_t) key[KEY_INR]; … … 319 331 * This function assumes interrupts are already disabled. 320 332 * 321 * @param key Keys (i.e. inr and devno).333 * @param key Keys (i.e. inr and devno). 322 334 * @param keys This is 2. 323 335 * @param item The item to compare the key with. 324 336 * 325 337 * @return True on match or false otherwise. 326 */ 327 bool irq_ht_compare(unative_t key[], size_t keys, link_t *item) 338 * 339 */ 340 bool irq_ht_compare(sysarg_t key[], size_t keys, link_t *item) 328 341 { 329 342 irq_t *irq = hash_table_get_instance(item, irq_t, link); 330 343 inr_t inr = (inr_t) key[KEY_INR]; 331 344 devno_t devno = (devno_t) key[KEY_DEVNO]; 332 345 333 346 bool rv; 334 347 335 spinlock_lock(&irq->lock);348 irq_spinlock_lock(&irq->lock, false); 336 349 if (devno == -1) { 337 350 /* Invoked by irq_dispatch_and_lock(). */ … … 345 358 /* unlock only on non-match */ 346 359 if (!rv) 347 spinlock_unlock(&irq->lock);348 360 irq_spinlock_unlock(&irq->lock, false); 361 349 362 return rv; 350 363 } … … 358 371 irq_t *irq __attribute__((unused)) 359 372 = hash_table_get_instance(lnk, irq_t, link); 360 spinlock_unlock(&irq->lock);373 irq_spinlock_unlock(&irq->lock, false); 361 374 } 362 375 … … 371 384 * 372 385 * @return Index into the hash table. 373 */ 374 size_t irq_lin_hash(unative_t key[]) 386 * 387 */ 388 size_t irq_lin_hash(sysarg_t key[]) 375 389 { 376 390 inr_t inr = (inr_t) key[KEY_INR]; … … 392 406 * This function assumes interrupts are already disabled. 393 407 * 394 * @param key Keys (i.e. inr and devno).408 * @param key Keys (i.e. inr and devno). 395 409 * @param keys This is 2. 396 410 * @param item The item to compare the key with. 397 411 * 398 412 * @return True on match or false otherwise. 399 */ 400 bool irq_lin_compare(unative_t key[], size_t keys, link_t *item) 413 * 414 */ 415 bool irq_lin_compare(sysarg_t key[], size_t keys, link_t *item) 401 416 { 402 417 irq_t *irq = list_get_instance(item, irq_t, link); … … 404 419 bool rv; 405 420 406 spinlock_lock(&irq->lock);421 irq_spinlock_lock(&irq->lock, false); 407 422 if (devno == -1) { 408 423 /* Invoked by irq_dispatch_and_lock() */ … … 415 430 /* unlock only on non-match */ 416 431 if (!rv) 417 spinlock_unlock(&irq->lock);432 irq_spinlock_unlock(&irq->lock, false); 418 433 419 434 return rv; … … 422 437 /** Unlock IRQ structure after hash_table_remove(). 423 438 * 424 * @param lnk Link in the removed and locked IRQ structure. 439 * @param lnk Link in the removed and locked IRQ structure. 440 * 425 441 */ 426 442 void irq_lin_remove(link_t *lnk) … … 428 444 irq_t *irq __attribute__((unused)) 429 445 = hash_table_get_instance(lnk, irq_t, link); 430 spinlock_unlock(&irq->lock);446 irq_spinlock_unlock(&irq->lock, false); 431 447 } 432 448
Note:
See TracChangeset
for help on using the changeset viewer.