Subversion Repositories HelenOS

Rev

Rev 4192 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4192 Rev 4263
Line 142... Line 142...
142
    unative_t method, irq_code_t *ucode)
142
    unative_t method, irq_code_t *ucode)
143
{
143
{
144
    ipl_t ipl;
144
    ipl_t ipl;
145
    irq_code_t *code;
145
    irq_code_t *code;
146
    irq_t *irq;
146
    irq_t *irq;
-
 
147
    link_t *hlp;
147
    unative_t key[] = {
148
    unative_t key[] = {
148
        (unative_t) inr,
149
        (unative_t) inr,
149
        (unative_t) devno
150
        (unative_t) devno
150
    };
151
    };
151
 
152
 
Line 176... Line 177...
176
     * Enlist the IRQ structure in the uspace IRQ hash table and the
177
     * Enlist the IRQ structure in the uspace IRQ hash table and the
177
     * answerbox's list.
178
     * answerbox's list.
178
     */
179
     */
179
    ipl = interrupts_disable();
180
    ipl = interrupts_disable();
180
    spinlock_lock(&irq_uspace_hash_table_lock);
181
    spinlock_lock(&irq_uspace_hash_table_lock);
-
 
182
    hlp = hash_table_find(&irq_uspace_hash_table, key);
-
 
183
    if (hlp) {
-
 
184
        irq_t *hirq = hash_table_get_instance(hlp, irq_t, link);
181
    spinlock_lock(&irq->lock);
185
        /* hirq is locked */
182
    spinlock_lock(&box->irq_lock);
186
        spinlock_unlock(&hirq->lock);
183
    if (hash_table_find(&irq_uspace_hash_table, key)) {
-
 
184
        code_free(code);
187
        code_free(code);
185
        spinlock_unlock(&box->irq_lock);
-
 
186
        spinlock_unlock(&irq->lock);
-
 
187
        spinlock_unlock(&irq_uspace_hash_table_lock);
188
        spinlock_unlock(&irq_uspace_hash_table_lock);
188
        free(irq);
189
        free(irq);
189
        interrupts_restore(ipl);
190
        interrupts_restore(ipl);
190
        return EEXISTS;
191
        return EEXISTS;
191
    }
192
    }
-
 
193
    spinlock_lock(&irq->lock);  /* not really necessary, but paranoid */
-
 
194
    spinlock_lock(&box->irq_lock);
192
    hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
195
    hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
193
    list_append(&irq->notif_cfg.link, &box->irq_head);
196
    list_append(&irq->notif_cfg.link, &box->irq_head);
194
    spinlock_unlock(&box->irq_lock);
197
    spinlock_unlock(&box->irq_lock);
195
    spinlock_unlock(&irq->lock);
198
    spinlock_unlock(&irq->lock);
196
    spinlock_unlock(&irq_uspace_hash_table_lock);
199
    spinlock_unlock(&irq_uspace_hash_table_lock);
Line 227... Line 230...
227
        spinlock_unlock(&irq_uspace_hash_table_lock);
230
        spinlock_unlock(&irq_uspace_hash_table_lock);
228
        interrupts_restore(ipl);
231
        interrupts_restore(ipl);
229
        return ENOENT;
232
        return ENOENT;
230
    }
233
    }
231
    irq = hash_table_get_instance(lnk, irq_t, link);
234
    irq = hash_table_get_instance(lnk, irq_t, link);
232
    spinlock_lock(&irq->lock);
235
    /* irq is locked */
233
    spinlock_lock(&box->irq_lock);
236
    spinlock_lock(&box->irq_lock);
234
   
237
   
235
    ASSERT(irq->notif_cfg.answerbox == box);
238
    ASSERT(irq->notif_cfg.answerbox == box);
236
   
239
   
237
    /* Free up the pseudo code and associated structures. */
240
    /* Free up the pseudo code and associated structures. */
238
    code_free(irq->notif_cfg.code);
241
    code_free(irq->notif_cfg.code);
239
 
242
 
240
    /* Remove the IRQ from the answerbox's list. */
243
    /* Remove the IRQ from the answerbox's list. */
241
    list_remove(&irq->notif_cfg.link);
244
    list_remove(&irq->notif_cfg.link);
242
 
245
 
-
 
246
    /*
-
 
247
     * We need to drop the IRQ lock now because hash_table_remove() will try
-
 
248
     * to reacquire it. That basically violates the natural locking order,
-
 
249
     * but a deadlock in hash_table_remove() is prevented by the fact that
-
 
250
     * we already held the IRQ lock and didn't drop the hash table lock in
-
 
251
     * the meantime.
-
 
252
     */
-
 
253
    spinlock_unlock(&irq->lock);
-
 
254
 
243
    /* Remove the IRQ from the uspace IRQ hash table. */
255
    /* Remove the IRQ from the uspace IRQ hash table. */
244
    hash_table_remove(&irq_uspace_hash_table, key, 2);
256
    hash_table_remove(&irq_uspace_hash_table, key, 2);
245
   
257
   
246
    spinlock_unlock(&irq_uspace_hash_table_lock);
258
    spinlock_unlock(&irq_uspace_hash_table_lock);
247
    spinlock_unlock(&irq->lock);
-
 
248
    spinlock_unlock(&box->irq_lock);
259
    spinlock_unlock(&box->irq_lock);
249
   
260
   
250
    /* Free up the IRQ structure. */
261
    /* Free up the IRQ structure. */
251
    free(irq);
262
    free(irq);
252
   
263
   
Line 296... Line 307...
296
        ASSERT(irq->notif_cfg.answerbox == box);
307
        ASSERT(irq->notif_cfg.answerbox == box);
297
       
308
       
298
        /* Unlist from the answerbox. */
309
        /* Unlist from the answerbox. */
299
        list_remove(&irq->notif_cfg.link);
310
        list_remove(&irq->notif_cfg.link);
300
       
311
       
301
        /* Remove from the hash table. */
-
 
302
        hash_table_remove(&irq_uspace_hash_table, key, 2);
-
 
303
       
-
 
304
        /* Free up the pseudo code and associated structures. */
312
        /* Free up the pseudo code and associated structures. */
305
        code_free(irq->notif_cfg.code);
313
        code_free(irq->notif_cfg.code);
306
       
314
       
-
 
315
        /*
-
 
316
         * We need to drop the IRQ lock now because hash_table_remove()
-
 
317
         * will try to reacquire it. That basically violates the natural
-
 
318
         * locking order, but a deadlock in hash_table_remove() is
-
 
319
         * prevented by the fact that we already held the IRQ lock and
-
 
320
         * didn't drop the hash table lock in the meantime.
-
 
321
         */
307
        spinlock_unlock(&irq->lock);
322
        spinlock_unlock(&irq->lock);
-
 
323
       
-
 
324
        /* Remove from the hash table. */
-
 
325
        hash_table_remove(&irq_uspace_hash_table, key, 2);
-
 
326
       
308
        free(irq);
327
        free(irq);
309
    }
328
    }
310
   
329
   
311
    spinlock_unlock(&box->irq_lock);
330
    spinlock_unlock(&box->irq_lock);
312
    spinlock_unlock(&irq_uspace_hash_table_lock);
331
    spinlock_unlock(&irq_uspace_hash_table_lock);