|
@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
|
|
}
|
|
}
|
|
|
|
|
|
static struct pci_raw_ops pci_sal_ops = {
|
|
static struct pci_raw_ops pci_sal_ops = {
|
|
- .read = pci_sal_read,
|
|
|
|
|
|
+ .read = pci_sal_read,
|
|
.write = pci_sal_write
|
|
.write = pci_sal_write
|
|
};
|
|
};
|
|
|
|
|
|
@@ -137,35 +137,98 @@ alloc_pci_controller (int seg)
|
|
return controller;
|
|
return controller;
|
|
}
|
|
}
|
|
|
|
|
|
-static u64 __devinit
|
|
|
|
-add_io_space (struct acpi_resource_address64 *addr)
|
|
|
|
|
|
+struct pci_root_info {
|
|
|
|
+ struct pci_controller *controller;
|
|
|
|
+ char *name;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static unsigned int
|
|
|
|
+new_space (u64 phys_base, int sparse)
|
|
{
|
|
{
|
|
- u64 offset;
|
|
|
|
- int sparse = 0;
|
|
|
|
|
|
+ u64 mmio_base;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- if (addr->address_translation_offset == 0)
|
|
|
|
- return IO_SPACE_BASE(0); /* part of legacy IO space */
|
|
|
|
-
|
|
|
|
- if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
|
|
|
|
- sparse = 1;
|
|
|
|
|
|
+ if (phys_base == 0)
|
|
|
|
+ return 0; /* legacy I/O port space */
|
|
|
|
|
|
- offset = (u64) ioremap(addr->address_translation_offset, 0);
|
|
|
|
|
|
+ mmio_base = (u64) ioremap(phys_base, 0);
|
|
for (i = 0; i < num_io_spaces; i++)
|
|
for (i = 0; i < num_io_spaces; i++)
|
|
- if (io_space[i].mmio_base == offset &&
|
|
|
|
|
|
+ if (io_space[i].mmio_base == mmio_base &&
|
|
io_space[i].sparse == sparse)
|
|
io_space[i].sparse == sparse)
|
|
- return IO_SPACE_BASE(i);
|
|
|
|
|
|
+ return i;
|
|
|
|
|
|
if (num_io_spaces == MAX_IO_SPACES) {
|
|
if (num_io_spaces == MAX_IO_SPACES) {
|
|
- printk("Too many IO port spaces\n");
|
|
|
|
|
|
+ printk(KERN_ERR "PCI: Too many IO port spaces "
|
|
|
|
+ "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
|
|
return ~0;
|
|
return ~0;
|
|
}
|
|
}
|
|
|
|
|
|
i = num_io_spaces++;
|
|
i = num_io_spaces++;
|
|
- io_space[i].mmio_base = offset;
|
|
|
|
|
|
+ io_space[i].mmio_base = mmio_base;
|
|
io_space[i].sparse = sparse;
|
|
io_space[i].sparse = sparse;
|
|
|
|
|
|
- return IO_SPACE_BASE(i);
|
|
|
|
|
|
+ return i;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static u64 __devinit
|
|
|
|
+add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
|
|
|
|
+{
|
|
|
|
+ struct resource *resource;
|
|
|
|
+ char *name;
|
|
|
|
+ u64 base, min, max, base_port;
|
|
|
|
+ unsigned int sparse = 0, space_nr, len;
|
|
|
|
+
|
|
|
|
+ resource = kzalloc(sizeof(*resource), GFP_KERNEL);
|
|
|
|
+ if (!resource) {
|
|
|
|
+ printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
|
|
|
|
+ info->name);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ len = strlen(info->name) + 32;
|
|
|
|
+ name = kzalloc(len, GFP_KERNEL);
|
|
|
|
+ if (!name) {
|
|
|
|
+ printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
|
|
|
|
+ info->name);
|
|
|
|
+ goto free_resource;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ min = addr->min_address_range;
|
|
|
|
+ max = min + addr->address_length - 1;
|
|
|
|
+ if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
|
|
|
|
+ sparse = 1;
|
|
|
|
+
|
|
|
|
+ space_nr = new_space(addr->address_translation_offset, sparse);
|
|
|
|
+ if (space_nr == ~0)
|
|
|
|
+ goto free_name;
|
|
|
|
+
|
|
|
|
+ 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->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->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);
|
|
|
|
+ insert_resource(&iomem_resource, resource);
|
|
|
|
+
|
|
|
|
+ return base_port;
|
|
|
|
+
|
|
|
|
+free_name:
|
|
|
|
+ kfree(name);
|
|
|
|
+free_resource:
|
|
|
|
+ kfree(resource);
|
|
|
|
+out:
|
|
|
|
+ return ~0;
|
|
}
|
|
}
|
|
|
|
|
|
static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
|
|
static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
|
|
@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data)
|
|
return AE_OK;
|
|
return AE_OK;
|
|
}
|
|
}
|
|
|
|
|
|
-struct pci_root_info {
|
|
|
|
- struct pci_controller *controller;
|
|
|
|
- char *name;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
|
static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
|
{
|
|
{
|
|
struct pci_root_info *info = data;
|
|
struct pci_root_info *info = data;
|
|
@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
|
} else if (addr.resource_type == ACPI_IO_RANGE) {
|
|
} else if (addr.resource_type == ACPI_IO_RANGE) {
|
|
flags = IORESOURCE_IO;
|
|
flags = IORESOURCE_IO;
|
|
root = &ioport_resource;
|
|
root = &ioport_resource;
|
|
- offset = add_io_space(&addr);
|
|
|
|
|
|
+ offset = add_io_space(info, &addr);
|
|
if (offset == ~0)
|
|
if (offset == ~0)
|
|
return AE_OK;
|
|
return AE_OK;
|
|
} else
|
|
} else
|
|
@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
|
window->resource.name = info->name;
|
|
window->resource.name = info->name;
|
|
window->resource.flags = flags;
|
|
window->resource.flags = flags;
|
|
window->resource.start = addr.min_address_range + offset;
|
|
window->resource.start = addr.min_address_range + offset;
|
|
- window->resource.end = addr.max_address_range + offset;
|
|
|
|
|
|
+ window->resource.end = window->resource.start + addr.address_length - 1;
|
|
window->resource.child = NULL;
|
|
window->resource.child = NULL;
|
|
window->offset = offset;
|
|
window->offset = offset;
|
|
|
|
|
|
@@ -739,7 +797,7 @@ int pci_vector_resources(int last, int nr_released)
|
|
{
|
|
{
|
|
int count = nr_released;
|
|
int count = nr_released;
|
|
|
|
|
|
- count += (IA64_LAST_DEVICE_VECTOR - last);
|
|
|
|
|
|
+ count += (IA64_LAST_DEVICE_VECTOR - last);
|
|
|
|
|
|
return count;
|
|
return count;
|
|
}
|
|
}
|