Rev 1932 | Rev 2064 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1932 | Rev 1933 | ||
|---|---|---|---|
| Line 174... | Line 174... | ||
| 174 | 174 | ||
| 175 | ipl = interrupts_disable(); |
175 | ipl = interrupts_disable(); |
| 176 | irq = irq_find_and_lock(inr, devno); |
176 | irq = irq_find_and_lock(inr, devno); |
| 177 | if (irq) { |
177 | if (irq) { |
| 178 | if (irq->notif_cfg.answerbox == box) { |
178 | if (irq->notif_cfg.answerbox == box) { |
| - | 179 | code_free(irq->notif_cfg.code); |
|
| 179 | irq->notif_cfg.notify = false; |
180 | irq->notif_cfg.notify = false; |
| 180 | irq->notif_cfg.answerbox = NULL; |
181 | irq->notif_cfg.answerbox = NULL; |
| 181 | irq->notif_cfg.code = NULL; |
182 | irq->notif_cfg.code = NULL; |
| 182 | irq->notif_cfg.method = 0; |
183 | irq->notif_cfg.method = 0; |
| 183 | irq->notif_cfg.counter = 0; |
184 | irq->notif_cfg.counter = 0; |
| - | 185 | ||
| - | 186 | spinlock_lock(&box->irq_lock); |
|
| 184 | code_free(irq->notif_cfg.code); |
187 | list_remove(&irq->notif_cfg.link); |
| - | 188 | spinlock_unlock(&box->irq_lock); |
|
| - | 189 | ||
| 185 | spinlock_unlock(&irq->lock); |
190 | spinlock_unlock(&irq->lock); |
| 186 | } |
191 | } |
| 187 | } |
192 | } |
| 188 | interrupts_restore(ipl); |
193 | interrupts_restore(ipl); |
| 189 | } |
194 | } |
| Line 196... | Line 201... | ||
| 196 | * @param method Method to be associated with the notification. |
201 | * @param method Method to be associated with the notification. |
| 197 | * @param ucode Uspace pointer to top-half pseudocode. |
202 | * @param ucode Uspace pointer to top-half pseudocode. |
| 198 | * |
203 | * |
| 199 | * @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success. |
204 | * @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success. |
| 200 | */ |
205 | */ |
| 201 | int |
- | |
| 202 | ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno, unative_t method, irq_code_t *ucode) |
206 | int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno, unative_t method, irq_code_t *ucode) |
| 203 | { |
207 | { |
| 204 | ipl_t ipl; |
208 | ipl_t ipl; |
| 205 | irq_code_t *code; |
209 | irq_code_t *code; |
| 206 | irq_t *irq; |
210 | irq_t *irq; |
| 207 | 211 | ||
| Line 230... | Line 234... | ||
| 230 | irq->notif_cfg.notify = true; |
234 | irq->notif_cfg.notify = true; |
| 231 | irq->notif_cfg.answerbox = box; |
235 | irq->notif_cfg.answerbox = box; |
| 232 | irq->notif_cfg.method = method; |
236 | irq->notif_cfg.method = method; |
| 233 | irq->notif_cfg.code = code; |
237 | irq->notif_cfg.code = code; |
| 234 | irq->notif_cfg.counter = 0; |
238 | irq->notif_cfg.counter = 0; |
| - | 239 | ||
| - | 240 | spinlock_lock(&box->irq_lock); |
|
| - | 241 | list_append(&irq->notif_cfg.link, &box->irq_head); |
|
| - | 242 | spinlock_unlock(&box->irq_lock); |
|
| - | 243 | ||
| 235 | spinlock_unlock(&irq->lock); |
244 | spinlock_unlock(&irq->lock); |
| 236 | interrupts_restore(ipl); |
245 | interrupts_restore(ipl); |
| 237 | 246 | ||
| 238 | return 0; |
247 | return 0; |
| 239 | } |
248 | } |
| Line 308... | Line 317... | ||
| 308 | } |
317 | } |
| 309 | } |
318 | } |
| 310 | 319 | ||
| 311 | /** Disconnect all IRQ notifications from an answerbox. |
320 | /** Disconnect all IRQ notifications from an answerbox. |
| 312 | * |
321 | * |
| - | 322 | * This function is effective because the answerbox contains |
|
| - | 323 | * list of all irq_t structures that are registered to |
|
| - | 324 | * send notifications to it. |
|
| - | 325 | * |
|
| 313 | * @param box Answerbox for which we want to carry out the cleanup. |
326 | * @param box Answerbox for which we want to carry out the cleanup. |
| 314 | */ |
327 | */ |
| 315 | void ipc_irq_cleanup(answerbox_t *box) |
328 | void ipc_irq_cleanup(answerbox_t *box) |
| 316 | { |
329 | { |
| - | 330 | ipl_t ipl; |
|
| - | 331 | ||
| - | 332 | loop: |
|
| - | 333 | ipl = interrupts_disable(); |
|
| - | 334 | spinlock_lock(&box->irq_lock); |
|
| - | 335 | ||
| - | 336 | while (box->irq_head.next != &box->irq_head) { |
|
| - | 337 | link_t *cur = box->irq_head.next; |
|
| - | 338 | irq_t *irq; |
|
| - | 339 | ||
| - | 340 | irq = list_get_instance(cur, irq_t, notif_cfg.link); |
|
| - | 341 | if (!spinlock_trylock(&irq->lock)) { |
|
| - | 342 | /* |
|
| - | 343 | * Avoid deadlock by trying again. |
|
| 317 | /* TODO */ |
344 | */ |
| - | 345 | spinlock_unlock(&box->irq_lock); |
|
| - | 346 | interrupts_restore(ipl); |
|
| - | 347 | goto loop; |
|
| - | 348 | } |
|
| - | 349 | ||
| - | 350 | ASSERT(irq->notif_cfg.answerbox == box); |
|
| - | 351 | ||
| - | 352 | list_remove(&irq->notif_cfg.link); |
|
| - | 353 | ||
| - | 354 | /* |
|
| - | 355 | * Don't forget to free any top-half pseudocode. |
|
| - | 356 | */ |
|
| - | 357 | code_free(irq->notif_cfg.code); |
|
| - | 358 | ||
| - | 359 | irq->notif_cfg.notify = false; |
|
| - | 360 | irq->notif_cfg.answerbox = NULL; |
|
| - | 361 | irq->notif_cfg.code = NULL; |
|
| - | 362 | irq->notif_cfg.method = 0; |
|
| - | 363 | irq->notif_cfg.counter = 0; |
|
| - | 364 | ||
| - | 365 | spinlock_unlock(&irq->lock); |
|
| - | 366 | } |
|
| - | 367 | ||
| - | 368 | spinlock_unlock(&box->irq_lock); |
|
| - | 369 | interrupts_restore(ipl); |
|
| 318 | } |
370 | } |
| 319 | 371 | ||
| 320 | /** @} |
372 | /** @} |
| 321 | */ |
373 | */ |