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;
}