in pci/pci.c [151:212]
static int add_io_space(struct device *dev, struct pci_root_info *info,
struct resource_entry *entry)
{
struct resource_entry *iospace;
struct resource *resource, *res = entry->res;
char *name;
unsigned long base, min, max, base_port;
unsigned int sparse = 0, space_nr, len;
len = strlen(info->common.name) + 32;
iospace = resource_list_create_entry(NULL, len);
if (!iospace) {
dev_err(dev, "PCI: No memory for %s I/O port space\n",
info->common.name);
return -ENOMEM;
}
if (res->flags & IORESOURCE_IO_SPARSE)
sparse = 1;
space_nr = new_space(entry->offset, sparse);
if (space_nr == ~0)
goto free_resource;
name = (char *)(iospace + 1);
min = res->start - entry->offset;
max = res->end - entry->offset;
base = __pa(io_space[space_nr].mmio_base);
base_port = IO_SPACE_BASE(space_nr);
snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->common.name,
base_port + min, base_port + max);
/*
* The SDM guarantees the legacy 0-64K space is sparse, but if the
* mapping is done by the processor (not the bridge), ACPI may not
* mark it as sparse.
*/
if (space_nr == 0)
sparse = 1;
resource = iospace->res;
resource->name = name;
resource->flags = IORESOURCE_MEM;
resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
if (insert_resource(&iomem_resource, resource)) {
dev_err(dev,
"can't allocate host bridge io space resource %pR\n",
resource);
goto free_resource;
}
entry->offset = base_port;
res->start = min + base_port;
res->end = max + base_port;
resource_list_add_tail(iospace, &info->io_resources);
return 0;
free_resource:
resource_list_free_entry(iospace);
return -ENOSPC;
}