Index: sys/kern/subr_intr.c =================================================================== --- sys/kern/subr_intr.c +++ sys/kern/subr_intr.c @@ -401,33 +401,25 @@ static inline int isrc_alloc_irq(struct intr_irqsrc *isrc) { - u_int maxirqs, irq; + u_int maxirqs; mtx_assert(&isrc_table_lock, MA_OWNED); maxirqs = intr_nirq; - if (irq_next_free >= maxirqs) - return (ENOSPC); - for (irq = irq_next_free; irq < maxirqs; irq++) { - if (irq_sources[irq] == NULL) - goto found; - } - for (irq = 0; irq < irq_next_free; irq++) { - if (irq_sources[irq] == NULL) + while (irq_next_free < maxirqs) { + if (irq_sources[irq_next_free] == NULL) goto found; + ++irq_next_free; } - irq_next_free = maxirqs; return (ENOSPC); found: - isrc->isrc_irq = irq; - irq_sources[irq] = isrc; + isrc->isrc_irq = irq_next_free; + irq_sources[irq_next_free] = isrc; - irq_next_free = irq + 1; - if (irq_next_free >= maxirqs) - irq_next_free = 0; + ++irq_next_free; return (0); } @@ -445,6 +437,10 @@ if (irq_sources[isrc->isrc_irq] != isrc) return (EINVAL); + /* Signal availability to isrc_alloc_irq(). */ + if (isrc->isrc_irq < irq_next_free) + irq_next_free = isrc->isrc_irq; + irq_sources[isrc->isrc_irq] = NULL; isrc->isrc_irq = INTR_IRQ_INVALID; /* just to be safe */ return (0);