int pnp_check_mem()

in resource.c [229:290]


int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
{
	int i;
	struct pnp_dev *tdev;
	struct resource *tres;
	resource_size_t *addr, *end, *taddr, *tend;

	addr = &res->start;
	end = &res->end;

	/* if the resource doesn't exist, don't complain about it */
	if (cannot_compare(res->flags))
		return 1;

	/* check if the resource is already in use, skip if the
	 * device is active because it itself may be in use */
	if (!dev->active) {
		if (!request_mem_region(*addr, length(addr, end), "pnp"))
			return 0;
		release_mem_region(*addr, length(addr, end));
	}

	/* check if the resource is reserved */
	for (i = 0; i < 8; i++) {
		int raddr = pnp_reserve_mem[i << 1];
		int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1;
		if (ranged_conflict(addr, end, &raddr, &rend))
			return 0;
	}

	/* check for internal conflicts */
	for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
		if (tres != res && tres->flags & IORESOURCE_MEM) {
			taddr = &tres->start;
			tend = &tres->end;
			if (ranged_conflict(addr, end, taddr, tend))
				return 0;
		}
	}

	/* check for conflicts with other pnp devices */
	pnp_for_each_dev(tdev) {
		if (tdev == dev)
			continue;
		for (i = 0;
		     (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i));
		     i++) {
			if (tres->flags & IORESOURCE_MEM) {
				if (cannot_compare(tres->flags))
					continue;
				if (tres->flags & IORESOURCE_WINDOW)
					continue;
				taddr = &tres->start;
				tend = &tres->end;
				if (ranged_conflict(addr, end, taddr, tend))
					return 0;
			}
		}
	}

	return 1;
}