/** * airq_iv_alloc - allocate irq bits from an interrupt vector * @iv: pointer to an interrupt vector structure * @num: number of consecutive irq bits to allocate * * Returns the bit number of the first irq in the allocated block of irqs, * or -1UL if no bit is available or the AIRQ_IV_ALLOC flag has not been * specified
*/ unsignedlong airq_iv_alloc(struct airq_iv *iv, unsignedlong num)
{ unsignedlong bit, i, flags;
if (!iv->avail || num == 0) return -1UL;
spin_lock_irqsave(&iv->lock, flags);
bit = find_first_bit_inv(iv->avail, iv->bits); while (bit + num <= iv->bits) { for (i = 1; i < num; i++) if (!test_bit_inv(bit + i, iv->avail)) break; if (i >= num) { /* Found a suitable block of irqs */ for (i = 0; i < num; i++)
clear_bit_inv(bit + i, iv->avail); if (bit + num >= iv->end)
iv->end = bit + num + 1; break;
}
bit = find_next_bit_inv(iv->avail, iv->bits, bit + i + 1);
} if (bit + num > iv->bits)
bit = -1UL;
spin_unlock_irqrestore(&iv->lock, flags); return bit;
}
EXPORT_SYMBOL(airq_iv_alloc);
/** * airq_iv_free - free irq bits of an interrupt vector * @iv: pointer to interrupt vector structure * @bit: number of the first irq bit to free * @num: number of consecutive irq bits to free
*/ void airq_iv_free(struct airq_iv *iv, unsignedlong bit, unsignedlong num)
{ unsignedlong i, flags;
if (!iv->avail || num == 0) return;
spin_lock_irqsave(&iv->lock, flags); for (i = 0; i < num; i++) { /* Clear (possibly left over) interrupt bit */
clear_bit_inv(bit + i, iv->vector); /* Make the bit positions available again */
set_bit_inv(bit + i, iv->avail);
} if (bit + num >= iv->end) { /* Find new end of bit-field */ while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail))
iv->end--;
}
spin_unlock_irqrestore(&iv->lock, flags);
}
EXPORT_SYMBOL(airq_iv_free);
/** * airq_iv_scan - scan interrupt vector for non-zero bits * @iv: pointer to interrupt vector structure * @start: bit number to start the search * @end: bit number to end the search * * Returns the bit number of the next non-zero interrupt bit, or * -1UL if the scan completed without finding any more any non-zero bits.
*/ unsignedlong airq_iv_scan(struct airq_iv *iv, unsignedlong start, unsignedlong end)
{ unsignedlong bit;
/* Find non-zero bit starting from 'ivs->next'. */
bit = find_next_bit_inv(iv->vector, end, start); if (bit >= end) return -1UL;
clear_bit_inv(bit, iv->vector); return bit;
}
EXPORT_SYMBOL(airq_iv_scan);
int __init airq_init(void)
{
airq_iv_cache = dma_pool_create("airq_iv_cache", cio_get_dma_css_dev(),
cache_line_size(),
cache_line_size(), PAGE_SIZE); if (!airq_iv_cache) return -ENOMEM; return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.