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 | */ |