/* Buddy allocator for MTT segments (currently not very efficient since it doesn't keep a free list and just searches linearly through the bitmaps)  */
static u32 mthca_buddy_alloc(struct mthca_buddy *buddy, int order)
/* Buddy allocator for MTT segments (currently not very efficient since it doesn't keep a free list and just searches linearly through the bitmaps)  */
static u32 mthca_buddy_alloc(struct mthca_buddy *buddy, int order)
{
	int o;
	int m;
	u32 seg;
	spin_lock(&buddy->lock);
	for (o = order; o <= buddy->max_order; ++o)
		if (buddy->num_free[o]) {
			m = 1 << (buddy->max_order - o);
			seg = find_first_bit(buddy->bits[o], m);
			if (seg < m)
				goto found;
		}
	spin_unlock(&buddy->lock);
	return -1;
 found:
	clear_bit(seg, buddy->bits[o]);
	--buddy->num_free[o];
	while (o > order) {
		--o;
		seg <<= 1;
		set_bit(seg ^ 1, buddy->bits[o]);
		++buddy->num_free[o];
	}
	spin_unlock(&buddy->lock);
	seg <<= order;
	return seg;
}