Changeset e3890b3f in mainline for kernel/generic/src/ddi/irq.c
- Timestamp:
- 2006-10-15T12:46:29Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2b017ba
- Parents:
- 63530c62
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ddi/irq.c
r63530c62 re3890b3f 32 32 /** 33 33 * @file 34 * @brief IRQ redirector.34 * @brief IRQ dispatcher. 35 35 * 36 36 * This file provides means of connecting IRQs with particular … … 57 57 * array. Next, when it is known that the IRQ numbers (aka INR's) 58 58 * are unique, the claim functions can always return IRQ_ACCEPT. 59 * 60 * 61 * Note about the irq_hash_table. 62 * 63 * The hash table is configured to use two keys: inr and devno. 64 * However, the hash index is computed only from inr. Moreover, 65 * if devno is -1, the match is based on the return value of 66 * the claim() function instead of on devno. 59 67 */ 60 68 … … 67 75 #include <arch.h> 68 76 77 #define KEY_INR 0 78 #define KEY_DEVNO 1 79 69 80 /** 70 81 * Spinlock protecting the hash table. … … 116 127 */ 117 128 if (inrs == chains) 118 hash_table_create(&irq_hash_table, chains, 1, &irq_lin_ops);129 hash_table_create(&irq_hash_table, chains, 2, &irq_lin_ops); 119 130 else 120 hash_table_create(&irq_hash_table, chains, 1, &irq_ht_ops);131 hash_table_create(&irq_hash_table, chains, 2, &irq_ht_ops); 121 132 } 122 133 … … 138 149 irq->notif_answerbox = NULL; 139 150 irq->code = NULL; 151 irq->method = 0; 140 152 atomic_set(&irq->counter, 0); 141 153 } … … 152 164 { 153 165 ipl_t ipl; 166 unative_t key[] = { 167 (unative_t) irq->inr, 168 (unative_t) irq->devno 169 }; 154 170 155 171 ipl = interrupts_disable(); 156 172 spinlock_lock(&irq_hash_table_lock); 157 hash_table_insert(&irq_hash_table, (void *) &irq->inr, &irq->link);173 hash_table_insert(&irq_hash_table, key, &irq->link); 158 174 spinlock_unlock(&irq_hash_table_lock); 159 175 interrupts_restore(ipl); … … 162 178 /** Dispatch the IRQ. 163 179 * 180 * We assume this function is only called from interrupt 181 * context (i.e. that interrupts are disabled prior to 182 * this call). 183 * 184 * This function attempts to lookup a fitting IRQ 185 * structure. In case of success, return with interrupts 186 * disabled and holding the respective structure. 187 * 164 188 * @param inr Interrupt number (aka inr or irq). 165 189 * 166 190 * @return IRQ structure of the respective device or NULL. 167 191 */ 168 irq_t *irq_dispatch(inr_t inr) 169 { 170 ipl_t ipl; 192 irq_t *irq_dispatch_and_lock(inr_t inr) 193 { 171 194 link_t *lnk; 172 173 ipl = interrupts_disable(); 195 unative_t key[] = { 196 (unative_t) inr, 197 (unative_t) -1 /* search will use claim() instead of devno */ 198 }; 199 174 200 spinlock_lock(&irq_hash_table_lock); 175 201 176 lnk = hash_table_find(&irq_hash_table, (void *) &inr);202 lnk = hash_table_find(&irq_hash_table, key); 177 203 if (lnk) { 178 204 irq_t *irq; … … 181 207 182 208 spinlock_unlock(&irq_hash_table_lock); 183 interrupts_restore(ipl);184 209 return irq; 185 210 } 186 211 187 212 spinlock_unlock(&irq_hash_table_lock); 188 interrupts_restore(ipl); 213 214 return NULL; 215 } 216 217 /** Find the IRQ structure corresponding to inr and devno. 218 * 219 * This functions attempts to lookup the IRQ structure 220 * corresponding to its arguments. On success, this 221 * function returns with interrups disabled, holding 222 * the lock of the respective IRQ structure. 223 * 224 * This function assumes interrupts are already disabled. 225 * 226 * @param inr INR being looked up. 227 * @param devno Devno being looked up. 228 * 229 * @return Locked IRQ structure on success or NULL on failure. 230 */ 231 irq_t *irq_find_and_lock(inr_t inr, devno_t devno) 232 { 233 link_t *lnk; 234 unative_t keys[] = { 235 (unative_t) inr, 236 (unative_t) devno 237 }; 238 239 spinlock_lock(&irq_hash_table_lock); 240 241 lnk = hash_table_find(&irq_hash_table, keys); 242 if (lnk) { 243 irq_t *irq; 244 245 irq = hash_table_get_instance(lnk, irq_t, link); 246 247 spinlock_unlock(&irq_hash_table_lock); 248 return irq; 249 } 250 251 spinlock_unlock(&irq_hash_table_lock); 189 252 190 253 return NULL; … … 198 261 * INRs. 199 262 * 200 * @param key Pointer to INR. 263 * The devno is not used to compute the hash. 264 * 265 * @param key The first of the keys is inr and the second is devno or -1. 201 266 * 202 267 * @return Index into the hash table. 203 268 */ 204 index_t irq_ht_hash(unative_t *key)205 { 206 inr_t *inr = (inr_t *) key;207 return *inr % irq_hash_table.entries;269 index_t irq_ht_hash(unative_t key[]) 270 { 271 inr_t inr = (inr_t) key[KEY_INR]; 272 return inr % irq_hash_table.entries; 208 273 } 209 274 210 275 /** Compare hash table element with a key. 211 276 * 212 * As usually, we do sort of a hack here. 213 * Even when the key matches the inr member, 214 * we ask the device to either accept 215 * or decline to service the interrupt. 216 * 217 * @param key Pointer to key (i.e. inr). 218 * @param keys This is 1. 277 * There are two things to note about this function. 278 * First, it is used for the more complex architecture setup 279 * in which there are way too many interrupt numbers (i.e. inr's) 280 * to arrange the hash table so that collisions occur only 281 * among same inrs of different devnos. So the explicit check 282 * for inr match must be done. 283 * Second, if devno is -1, the second key (i.e. devno) is not 284 * used for the match and the result of the claim() function 285 * is used instead. 286 * 287 * This function assumes interrupts are already disabled. 288 * 289 * @param key Keys (i.e. inr and devno). 290 * @param keys This is 2. 219 291 * @param item The item to compare the key with. 220 292 * 221 293 * @return True on match or false otherwise. 222 294 */ 223 bool irq_ht_compare(unative_t *key, count_t keys, link_t *item)295 bool irq_ht_compare(unative_t key[], count_t keys, link_t *item) 224 296 { 225 297 irq_t *irq = hash_table_get_instance(item, irq_t, link); 226 inr_t *inr = (inr_t *) key; 298 inr_t inr = (inr_t) key[KEY_INR]; 299 devno_t devno = (devno_t) key[KEY_DEVNO]; 300 227 301 bool rv; 228 302 229 303 spinlock_lock(&irq->lock); 230 rv = ((irq->inr == *inr) && (irq->claim() == IRQ_ACCEPT)); 231 spinlock_unlock(&irq->lock); 304 if (devno == -1) { 305 /* Invoked by irq_dispatch(). */ 306 rv = ((irq->inr == inr) && (irq->claim() == IRQ_ACCEPT)); 307 } else { 308 /* Invoked by irq_find(). */ 309 rv = ((irq->inr == inr) && (irq->devno == devno)); 310 } 311 312 /* unlock only on non-match */ 313 if (!rv) 314 spinlock_unlock(&irq->lock); 232 315 233 316 return rv; … … 241 324 * INRs. 242 325 * 243 * @param key INR.326 * @param key The first of the keys is inr and the second is devno or -1. 244 327 * 245 328 * @return Index into the hash table. 246 329 */ 247 index_t irq_lin_hash(unative_t *key)248 { 249 inr_t *inr = (inr_t *) key;250 return *inr;330 index_t irq_lin_hash(unative_t key[]) 331 { 332 inr_t inr = (inr_t) key[KEY_INR]; 333 return inr; 251 334 } 252 335 253 336 /** Compare hash table element with a key. 254 337 * 255 * As usually, we do sort of a hack here. 256 * We don't compare the inr member with 257 * the key because we know that there are 258 * no collision between different keys. 259 * We only ask the device to either accept 260 * or decline to service the interrupt. 261 * 262 * @param key Pointer to key (i.e. inr). 263 * @param keys This is 1. 338 * There are two things to note about this function. 339 * First, it is used for the less complex architecture setup 340 * in which there are not too many interrupt numbers (i.e. inr's) 341 * to arrange the hash table so that collisions occur only 342 * among same inrs of different devnos. So the explicit check 343 * for inr match is not done. 344 * Second, if devno is -1, the second key (i.e. devno) is not 345 * used for the match and the result of the claim() function 346 * is used instead. 347 * 348 * This function assumes interrupts are already disabled. 349 * 350 * @param key Keys (i.e. inr and devno). 351 * @param keys This is 2. 264 352 * @param item The item to compare the key with. 265 353 * 266 354 * @return True on match or false otherwise. 267 355 */ 268 bool irq_lin_compare(unative_t *key, count_t keys, link_t *item)356 bool irq_lin_compare(unative_t key[], count_t keys, link_t *item) 269 357 { 270 358 irq_t *irq = list_get_instance(item, irq_t, link); 359 devno_t devno = (devno_t) key[KEY_DEVNO]; 271 360 bool rv; 272 361 273 362 spinlock_lock(&irq->lock); 274 rv = (irq->claim() == IRQ_ACCEPT); 275 spinlock_unlock(&irq->lock); 363 if (devno == -1) { 364 /* Invoked by irq_dispatch() */ 365 rv = (irq->claim() == IRQ_ACCEPT); 366 } else { 367 /* Invoked by irq_find() */ 368 rv = (irq->devno == devno); 369 } 370 371 /* unlock only on non-match */ 372 if (!rv) 373 spinlock_unlock(&irq->lock); 276 374 277 375 return rv;
Note:
See TracChangeset
for help on using the changeset viewer.