Subversion Repositories HelenOS

Rev

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