static int pnp_assign_irq()

in manager.c [132:188]


static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
{
	struct resource *res, local_res;
	int i;

	/* IRQ priority: this table is good for i386 */
	static unsigned short xtab[16] = {
		5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
	};

	res = pnp_find_resource(dev, rule->flags, IORESOURCE_IRQ, idx);
	if (res) {
		pnp_dbg(&dev->dev, "  irq %d already set to %d flags %#lx\n",
			idx, (int) res->start, res->flags);
		return 0;
	}

	res = &local_res;
	res->flags = rule->flags | IORESOURCE_AUTO;
	res->start = -1;
	res->end = -1;

	if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
		res->flags |= IORESOURCE_DISABLED;
		pnp_dbg(&dev->dev, "  irq %d disabled\n", idx);
		goto __add;
	}

	/* TBD: need check for >16 IRQ */
	res->start = find_next_bit(rule->map.bits, PNP_IRQ_NR, 16);
	if (res->start < PNP_IRQ_NR) {
		res->end = res->start;
		goto __add;
	}
	for (i = 0; i < 16; i++) {
		if (test_bit(xtab[i], rule->map.bits)) {
			res->start = res->end = xtab[i];
			if (pnp_check_irq(dev, res))
				goto __add;
		}
	}

	if (rule->flags & IORESOURCE_IRQ_OPTIONAL) {
		res->start = -1;
		res->end = -1;
		res->flags |= IORESOURCE_DISABLED;
		pnp_dbg(&dev->dev, "  irq %d disabled (optional)\n", idx);
		goto __add;
	}

	pnp_dbg(&dev->dev, "  couldn't assign irq %d\n", idx);
	return -EBUSY;

__add:
	pnp_add_irq_resource(dev, res->start, res->flags);
	return 0;
}