mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-28 10:04:14 +00:00
PCI: Fix bus resource assignment on 32 bits with 64b resources
The current pci_assign_unassigned_resources() code doesn't work properly on 32 bits platforms with 64 bits resources. The main reason is the use of unsigned long in various places instead of resource_size_t. This is a pre-requisite for making powerpc use the generic code instead of its own half-useful implementation. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
f07234b66a
commit
c40a22e0ce
2 changed files with 42 additions and 26 deletions
|
@ -89,8 +89,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
|
||||||
* The IO resource is allocated a range twice as large as it
|
* The IO resource is allocated a range twice as large as it
|
||||||
* would normally need. This allows us to set both IO regs.
|
* would normally need. This allows us to set both IO regs.
|
||||||
*/
|
*/
|
||||||
printk(" IO window: %08lx-%08lx\n",
|
printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
|
||||||
region.start, region.end);
|
(unsigned long)region.start,
|
||||||
|
(unsigned long)region.end);
|
||||||
pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
|
pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
|
||||||
region.start);
|
region.start);
|
||||||
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
|
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
|
||||||
|
@ -99,8 +100,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
|
||||||
|
|
||||||
pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]);
|
pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]);
|
||||||
if (bus->resource[1]->flags & IORESOURCE_IO) {
|
if (bus->resource[1]->flags & IORESOURCE_IO) {
|
||||||
printk(" IO window: %08lx-%08lx\n",
|
printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
|
||||||
region.start, region.end);
|
(unsigned long)region.start,
|
||||||
|
(unsigned long)region.end);
|
||||||
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
|
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
|
||||||
region.start);
|
region.start);
|
||||||
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
|
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
|
||||||
|
@ -109,8 +111,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
|
||||||
|
|
||||||
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
|
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
|
||||||
if (bus->resource[2]->flags & IORESOURCE_MEM) {
|
if (bus->resource[2]->flags & IORESOURCE_MEM) {
|
||||||
printk(" PREFETCH window: %08lx-%08lx\n",
|
printk(KERN_INFO " PREFETCH window: 0x%08lx-0x%08lx\n",
|
||||||
region.start, region.end);
|
(unsigned long)region.start,
|
||||||
|
(unsigned long)region.end);
|
||||||
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
|
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
|
||||||
region.start);
|
region.start);
|
||||||
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
|
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
|
||||||
|
@ -119,8 +122,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
|
||||||
|
|
||||||
pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]);
|
pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]);
|
||||||
if (bus->resource[3]->flags & IORESOURCE_MEM) {
|
if (bus->resource[3]->flags & IORESOURCE_MEM) {
|
||||||
printk(" MEM window: %08lx-%08lx\n",
|
printk(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
|
||||||
region.start, region.end);
|
(unsigned long)region.start,
|
||||||
|
(unsigned long)region.end);
|
||||||
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
|
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
|
||||||
region.start);
|
region.start);
|
||||||
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
|
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
|
||||||
|
@ -145,7 +149,7 @@ pci_setup_bridge(struct pci_bus *bus)
|
||||||
{
|
{
|
||||||
struct pci_dev *bridge = bus->self;
|
struct pci_dev *bridge = bus->self;
|
||||||
struct pci_bus_region region;
|
struct pci_bus_region region;
|
||||||
u32 l, io_upper16;
|
u32 l, bu, lu, io_upper16;
|
||||||
|
|
||||||
DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
|
DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
|
||||||
|
|
||||||
|
@ -159,7 +163,8 @@ pci_setup_bridge(struct pci_bus *bus)
|
||||||
/* Set up upper 16 bits of I/O base/limit. */
|
/* Set up upper 16 bits of I/O base/limit. */
|
||||||
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
|
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
|
||||||
DBG(KERN_INFO " IO window: %04lx-%04lx\n",
|
DBG(KERN_INFO " IO window: %04lx-%04lx\n",
|
||||||
region.start, region.end);
|
(unsigned long)region.start,
|
||||||
|
(unsigned long)region.end);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Clear upper 16 bits of I/O base/limit. */
|
/* Clear upper 16 bits of I/O base/limit. */
|
||||||
|
@ -180,8 +185,9 @@ pci_setup_bridge(struct pci_bus *bus)
|
||||||
if (bus->resource[1]->flags & IORESOURCE_MEM) {
|
if (bus->resource[1]->flags & IORESOURCE_MEM) {
|
||||||
l = (region.start >> 16) & 0xfff0;
|
l = (region.start >> 16) & 0xfff0;
|
||||||
l |= region.end & 0xfff00000;
|
l |= region.end & 0xfff00000;
|
||||||
DBG(KERN_INFO " MEM window: %08lx-%08lx\n",
|
DBG(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
|
||||||
region.start, region.end);
|
(unsigned long)region.start,
|
||||||
|
(unsigned long)region.end);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l = 0x0000fff0;
|
l = 0x0000fff0;
|
||||||
|
@ -195,12 +201,18 @@ pci_setup_bridge(struct pci_bus *bus)
|
||||||
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
|
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
|
||||||
|
|
||||||
/* Set up PREF base/limit. */
|
/* Set up PREF base/limit. */
|
||||||
|
bu = lu = 0;
|
||||||
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
|
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
|
||||||
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
|
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
|
||||||
l = (region.start >> 16) & 0xfff0;
|
l = (region.start >> 16) & 0xfff0;
|
||||||
l |= region.end & 0xfff00000;
|
l |= region.end & 0xfff00000;
|
||||||
DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n",
|
#ifdef CONFIG_RESOURCES_64BIT
|
||||||
region.start, region.end);
|
bu = region.start >> 32;
|
||||||
|
lu = region.end >> 32;
|
||||||
|
#endif
|
||||||
|
DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n",
|
||||||
|
(unsigned long long)region.start,
|
||||||
|
(unsigned long long)region.end);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l = 0x0000fff0;
|
l = 0x0000fff0;
|
||||||
|
@ -208,8 +220,9 @@ pci_setup_bridge(struct pci_bus *bus)
|
||||||
}
|
}
|
||||||
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
|
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
|
||||||
|
|
||||||
/* Clear out the upper 32 bits of PREF base. */
|
/* Set the upper 32 bits of PREF base & limit. */
|
||||||
pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
|
pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
|
||||||
|
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
|
||||||
|
|
||||||
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
|
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
|
||||||
}
|
}
|
||||||
|
@ -323,8 +336,8 @@ static void pbus_size_io(struct pci_bus *bus)
|
||||||
static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
|
static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
|
||||||
{
|
{
|
||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
unsigned long min_align, align, size;
|
resource_size_t min_align, align, size;
|
||||||
unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */
|
resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
|
||||||
int order, max_order;
|
int order, max_order;
|
||||||
struct resource *b_res = find_free_bus_resource(bus, type);
|
struct resource *b_res = find_free_bus_resource(bus, type);
|
||||||
|
|
||||||
|
@ -340,7 +353,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
|
||||||
|
|
||||||
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||||
struct resource *r = &dev->resource[i];
|
struct resource *r = &dev->resource[i];
|
||||||
unsigned long r_size;
|
resource_size_t r_size;
|
||||||
|
|
||||||
if (r->parent || (r->flags & mask) != type)
|
if (r->parent || (r->flags & mask) != type)
|
||||||
continue;
|
continue;
|
||||||
|
@ -350,10 +363,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
|
||||||
order = __ffs(align) - 20;
|
order = __ffs(align) - 20;
|
||||||
if (order > 11) {
|
if (order > 11) {
|
||||||
printk(KERN_WARNING "PCI: region %s/%d "
|
printk(KERN_WARNING "PCI: region %s/%d "
|
||||||
"too large: %llx-%llx\n",
|
"too large: 0x%016llx-0x%016llx\n",
|
||||||
pci_name(dev), i,
|
pci_name(dev), i,
|
||||||
(unsigned long long)r->start,
|
(unsigned long long)r->start,
|
||||||
(unsigned long long)r->end);
|
(unsigned long long)r->end);
|
||||||
r->flags = 0;
|
r->flags = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -372,8 +385,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
|
||||||
align = 0;
|
align = 0;
|
||||||
min_align = 0;
|
min_align = 0;
|
||||||
for (order = 0; order <= max_order; order++) {
|
for (order = 0; order <= max_order; order++) {
|
||||||
unsigned long align1 = 1UL << (order + 20);
|
#ifdef CONFIG_RESOURCES_64BIT
|
||||||
|
resource_size_t align1 = 1ULL << (order + 20);
|
||||||
|
#else
|
||||||
|
resource_size_t align1 = 1U << (order + 20);
|
||||||
|
#endif
|
||||||
if (!align)
|
if (!align)
|
||||||
min_align = align1;
|
min_align = align1;
|
||||||
else if (ALIGN(align + min_align, min_align) < align1)
|
else if (ALIGN(align + min_align, min_align) < align1)
|
||||||
|
|
|
@ -309,8 +309,8 @@ struct pci_raw_ops {
|
||||||
extern struct pci_raw_ops *raw_pci_ops;
|
extern struct pci_raw_ops *raw_pci_ops;
|
||||||
|
|
||||||
struct pci_bus_region {
|
struct pci_bus_region {
|
||||||
unsigned long start;
|
resource_size_t start;
|
||||||
unsigned long end;
|
resource_size_t end;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pci_dynids {
|
struct pci_dynids {
|
||||||
|
|
Loading…
Add table
Reference in a new issue