Commit b64958d9 authored by Russell King's avatar Russell King

[PCI] pci-9: Kill per-architecture pcibios_update_resource()

Kill pcibios_update_resource(), replacing it with pci_update_resource().
pci_update_resource() uses pcibios_resource_to_bus() to convert a
resource to a device BAR - the transformation should be exactly the
same as the transformation used for the PCI bridges.

pci_update_resource "knows" about 64-bit BARs, but doesn't attempt to
set the high 32-bits to anything non-zero - currently no architecture
attempts to do something different.  If anyone cares, please fix; I'm
going to reflect current behaviour for the time being.

Ivan pointed out the following architectures need to examine their
pcibios_update_resource() implementation - they should make sure that
this new implementation does the right thing.  #warning's have been
added where appropriate.

	ia64
	mips
	mips64

This cset also includes a fix for the problem reported by AKPM where
64-bit arch compilers complain about the resource mask being placed
in a u32.
parent 2ef9c88b
......@@ -264,45 +264,6 @@ pcibios_fixup_bus(struct pci_bus *bus)
}
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
struct pci_controller *hose = dev->sysdata;
struct resource *root;
int where;
u32 reg;
if (resource < PCI_ROM_RESOURCE)
where = PCI_BASE_ADDRESS_0 + (resource * 4);
else if (resource == PCI_ROM_RESOURCE)
where = dev->rom_base_reg;
else {
return; /* Don't update non-standard resources here. */
}
/* Point root at the hose root. */
if (res->flags & IORESOURCE_IO)
root = hose->io_space;
else if (res->flags & IORESOURCE_MEM)
root = hose->mem_space;
else {
return; /* Don't update non-standard resources here. */
}
reg = (res->start - root->start) | (res->flags & 0xf);
pci_write_config_dword(dev, where, reg);
if ((res->flags & (PCI_BASE_ADDRESS_SPACE
| PCI_BASE_ADDRESS_MEM_TYPE_MASK))
== (PCI_BASE_ADDRESS_SPACE_MEMORY
| PCI_BASE_ADDRESS_MEM_TYPE_64)) {
pci_write_config_dword(dev, where+4, 0);
printk(KERN_WARNING "PCI: dev %s type 64-bit\n", dev->dev.name);
}
/* ??? FIXME -- record old value for shutdown. */
}
void __init
pcibios_update_irq(struct pci_dev *dev, int irq)
{
......
......@@ -259,47 +259,6 @@ struct pci_fixup pcibios_fixups[] = {
}, { 0 }
};
void __devinit
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
struct pci_sys_data *sys = dev->sysdata;
u32 val, check;
int reg;
if (debug_pci)
printk("PCI: Assigning %3s %08lx to %s\n",
res->flags & IORESOURCE_IO ? "IO" : "MEM",
res->start, dev->dev.name);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
reg = dev->rom_base_reg;
} else {
/* Somebody might have asked allocation of a
* non-standard resource.
*/
return;
}
val = res->start;
if (res->flags & IORESOURCE_MEM)
val -= sys->mem_offset;
else
val -= sys->io_offset;
val |= res->flags & PCI_REGION_FLAG_MASK;
pci_write_config_dword(dev, reg, val);
pci_read_config_dword(dev, reg, &check);
if ((val ^ check) & ((val & PCI_BASE_ADDRESS_SPACE_IO) ?
PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name,
resource, val, check);
}
}
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
{
if (debug_pci)
......
......@@ -33,34 +33,6 @@
#include "pci.h"
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
new |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Somebody might have asked allocation of a non-standard resource */
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
......
......@@ -143,22 +143,7 @@ pcibios_fixup_bus (struct pci_bus *b)
return;
}
void __devinit
pcibios_update_resource (struct pci_dev *dev, struct resource *res,
int resource)
{
unsigned long where, size;
u32 reg;
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
/* FIXME - this doesn't work for PCI-PCI bridges. */
reg = (reg & size) | (((u32)(res->start - res->parent->start)) & ~size);
pci_write_config_dword(dev, where, reg);
/* ??? FIXME -- record old value for shutdown. */
}
#warning pcibios_update_resource() is now a generic implementation - please check
void __devinit
pcibios_update_irq (struct pci_dev *dev, int irq)
......
......@@ -336,37 +336,6 @@ int pcibios_enable_device(struct pci_dev *dev)
return pcibios_enable_resources(dev);
}
void pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4 * resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/*
* Somebody might have asked allocation of a non-standard
* resource
*/
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) &
((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
void pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
......
......@@ -400,37 +400,6 @@ int pcibios_enable_device(struct pci_dev *dev)
return pcibios_enable_resources(dev);
}
void pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4 * resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/*
* Somebody might have asked allocation of a non-standard
* resource
*/
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) &
((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
void pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
......
......@@ -170,11 +170,3 @@ pcibios_align_resource(void *data, struct resource *res,
/* this should not be called */
MIPS_ASSERT(1 == 0);
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
/* this should not be called */
MIPS_ASSERT(1 == 0);
}
......@@ -785,39 +785,6 @@ int pcibios_enable_device(struct pci_dev *dev)
return pcibios_enable_resources(dev);
}
void pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
return;
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4 * resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/*
* Somebody might have asked allocation of a non-standard
* resource
*/
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) &
((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
void pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
......
......@@ -196,20 +196,7 @@ pcibios_setup(char *str)
return str;
}
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
unsigned long where, size;
u32 reg;
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
/* FIXME - this doesn't work for PCI-PCI bridges. */
reg = (reg & size) | (((u32)(res->start - res->parent->start)) & ~size);
pci_write_config_dword(dev, where, reg);
}
#warning pcibios_update_resource() is now a generic implementation - please check
void __init pcibios_fixup_bus(struct pci_bus *b)
{
......
......@@ -166,10 +166,3 @@ pcibios_align_resource(void *data, struct resource *res,
{
/* this should not be called */
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
/* this should not be called */
}
......@@ -248,20 +248,7 @@ struct pci_fixup pcibios_fixups[] = {
{ 0 }
};
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
unsigned long where, size;
u32 reg;
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
/* FIXME - this doesn't work for PCI-PCI bridges. */
reg = (reg & size) | (((u32)(res->start - res->parent->start)) & ~size);
pci_write_config_dword(dev, where, reg);
}
#warning pcibios_update_resource() is now a generic implementation - please check
/*
* Called after each bus is probed, but before its children
......
......@@ -137,34 +137,6 @@ pcibios_fixup_bus(struct pci_bus *b)
{
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
new |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Somebody might have asked allocation of a non-standard resource */
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
void __init pcibios_init(void)
{
struct pci_ops *ops = &sni_pci_ops;
......
......@@ -307,20 +307,7 @@ struct pci_fixup pcibios_fixups[] = {
{ 0 }
};
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
unsigned long where, size;
u32 reg;
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
/* FIXME - this doesn't work for PCI-PCI bridges. */
reg = (reg & size) | (((u32)(res->start - res->parent->start)) & ~size);
pci_write_config_dword(dev, where, reg);
}
#warning pcibios_update_resource() is now a generic implementation - please check
unsigned __init int pcibios_assign_all_busses(void)
{
......
......@@ -214,20 +214,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
unsigned long where, size;
u32 reg;
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
/* FIXME - this doesn't work for PCI-PCI bridges. */
reg = (reg & size) | (((u32)(res->start - res->parent->start)) & ~size);
pci_write_config_dword(dev, where, reg);
}
#warning pcibios_update_resource() is now a generic implementation - please check
void __init
pcibios_fixup_bus(struct pci_bus *b)
......
......@@ -333,11 +333,6 @@ void __init pcibios_align_resource (void *data, struct resource *res,
{
}
void __init pcibios_update_resource (struct pci_dev *dev, struct resource *res,
int resource)
{
}
void __init pcibios_update_irq (struct pci_dev *dev, int irq)
{
pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
......
......@@ -192,73 +192,6 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
}
/* ------------------------------------
**
** Program one BAR in PCI config space.
**
** ------------------------------------
** PAT PDC systems need this routine. PA legacy PDC does not.
**
** When BAR's are configured by linux, this routine will update
** configuration space with the "normalized" address. "root" indicates
** where the range starts and res is some portion of that range.
**
** VCLASS: For all PA-RISC systems except V-class, root->start would be zero.
**
** PAT PDC can tell us which MMIO ranges are available or already in use.
** I/O port space and such are not memory mapped anyway for PA-Risc.
*/
void __devinit
pcibios_update_resource(
struct pci_dev *dev,
struct resource *res,
int barnum
)
{
int where;
u32 barval = 0;
DBG_RES("pcibios_update_resource(%s, ..., %d) [%lx,%lx]/%x\n",
dev->slot_name,
barnum, res->start, res->end, (int) res->flags);
if (barnum >= PCI_BRIDGE_RESOURCES) {
/* handled in PCI-PCI bridge specific support */
return;
}
if (barnum == PCI_ROM_RESOURCE) {
where = PCI_ROM_ADDRESS;
} else {
/* 0-5 standard PCI "regions" */
where = PCI_BASE_ADDRESS_0 + (barnum * 4);
}
if (res->flags & IORESOURCE_IO) {
barval = PCI_PORT_ADDR(res->start);
} else if (res->flags & IORESOURCE_MEM) {
barval = PCI_BUS_ADDR(HBA_DATA(dev->bus->dev->platform_data), res->start);
} else {
panic("pcibios_update_resource() WTF? flags not IO or MEM");
}
pci_write_config_dword(dev, where, barval);
/* XXX FIXME - Elroy does support 64-bit (dual cycle) addressing.
** But at least one device (Symbios 53c896) which has 64-bit BAR
** doesn't actually work right with dual cycle addresses.
** So ignore the whole mess for now.
*/
if ((res->flags & (PCI_BASE_ADDRESS_SPACE
| PCI_BASE_ADDRESS_MEM_TYPE_MASK))
== (PCI_BASE_ADDRESS_SPACE_MEMORY
| PCI_BASE_ADDRESS_MEM_TYPE_64)) {
pci_write_config_dword(dev, where+4, 0);
DBGC("PCIBIOS: dev %s type 64-bit\n", dev->name);
}
}
/*
** Called by pci_set_master() - a driver interface.
**
......
......@@ -93,46 +93,6 @@ fixup_broken_pcnet32(struct pci_dev* dev)
}
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
struct pci_controller* hose = dev->sysdata;
unsigned long io_offset;
new = res->start;
res->flags &= ~IORESOURCE_UNSET;
if (hose && res->flags & IORESOURCE_IO) {
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
new -= io_offset;
}
if (hose && res->flags & IORESOURCE_MEM)
new -= hose->pci_mem_offset;
new |= (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Somebody might have asked allocation of a non-standard resource */
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
printk(KERN_INFO "PCI: moved device %s resource %d (%lx) to %x\n",
dev->slot_name, resource, res->flags,
new & ~PCI_REGION_FLAG_MASK);
}
static void
pcibios_fixup_resources(struct pci_dev *dev)
{
......
......@@ -127,37 +127,6 @@ struct pci_dev *pci_find_dev_by_addr(unsigned long addr)
return NULL;
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
struct pci_controller* hose = PCI_GET_PHB_PTR(dev);
new = res->start;
if (hose && res->flags & IORESOURCE_MEM)
new -= hose->pci_mem_offset;
new |= (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Somebody might have asked allocation of a non-standard resource */
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
static void
pcibios_fixup_resources(struct pci_dev* dev)
{
......
......@@ -6,7 +6,6 @@
* This is GPL'd.
*
* Provided here are generic versions of:
* pcibios_update_resource()
* pcibios_align_resource()
* pcibios_enable_device()
* pcibios_set_master()
......@@ -25,34 +24,6 @@
#include <linux/pci.h>
#include <linux/init.h>
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
new |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Somebody might have asked allocation of a non-standard resource */
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
......
......@@ -854,13 +854,6 @@ char * __init pcibios_setup(char *str)
return str;
}
/*
*/
void pcibios_update_resource(struct pci_dev *pdev, struct resource *res,
int index)
{
}
void pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
......
......@@ -470,20 +470,10 @@ int pci_assign_resource(struct pci_dev *pdev, int resource)
return err;
}
void pcibios_update_resource(struct pci_dev *pdev, struct resource *res,
int index)
{
}
void pcibios_update_irq(struct pci_dev *pdev, int irq)
{
}
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges)
{
}
void pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
......
......@@ -287,43 +287,20 @@ void __devinit pcibios_update_irq (struct pci_dev *dev, int irq)
pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
}
void __nomods_init
pcibios_update_resource (struct pci_dev *dev, struct resource *r, int resource)
void __devinit
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
struct resource *res)
{
u32 new, check;
int reg;
unsigned long offset = 0;
if (r->flags & IORESOURCE_IO)
new = (((r->start - MB_A_PCI_IO_ADDR)
& PCI_BASE_ADDRESS_IO_MASK)
| PCI_BASE_ADDRESS_SPACE_IO);
else if (r->flags & IORESOURCE_MEM)
new = (((r->start - MB_A_PCI_MEM_ADDR)
& PCI_BASE_ADDRESS_MEM_MASK)
| PCI_BASE_ADDRESS_MEM_TYPE_32
| ((r->flags & IORESOURCE_PREFETCH)
? PCI_BASE_ADDRESS_MEM_PREFETCH
: 0)
| PCI_BASE_ADDRESS_SPACE_MEMORY);
else
panic ("pcibios_update_resource: unknown resource type");
if (resource < 6)
reg = PCI_BASE_ADDRESS_0 + 4*resource;
else if (resource == PCI_ROM_RESOURCE) {
r->flags |= PCI_ROM_ADDRESS_ENABLE;
new |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else
return;
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk (KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
if (res->flags & IORESOURCE_IO) {
offset = MB_A_PCI_IO_ADDR;
} else if (res->flags & IORESOURCE_MEM) {
offset = MB_A_PCI_MEM_ADDR;
}
region->start = res->start - offset;
region->end = res->end - offset;
}
......
......@@ -33,34 +33,6 @@
#include "pci.h"
void
pcibios_update_resource(struct pci_dev *dev, struct resource *res,
int resource)
{
u32 new, check;
int reg;
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
if (resource < 6) {
reg = PCI_BASE_ADDRESS_0 + 4*resource;
} else if (resource == PCI_ROM_RESOURCE) {
res->flags |= PCI_ROM_ADDRESS_ENABLE;
new |= PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Somebody might have asked allocation of a non-standard resource */
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
new, check);
}
}
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
......
......@@ -33,6 +33,59 @@
#endif
static void
pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
{
struct pci_bus_region region;
u32 new, check, mask;
int reg;
pcibios_resource_to_bus(dev, &region, res);
DBGC((KERN_ERR " got res [%lx:%lx] bus [%lx:%lx] for "
"resource %d of %s\n", res->start, res->end,
region.start, region.end, resno, dev->dev.name));
new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
if (res->flags & IORESOURCE_IO)
mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
else
mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
if (resno < 6) {
reg = PCI_BASE_ADDRESS_0 + 4 * resno;
} else if (resno == PCI_ROM_RESOURCE) {
new |= res->flags & PCI_ROM_ADDRESS_ENABLE;
reg = dev->rom_base_reg;
} else {
/* Hmm, non-standard resource. */
printk("PCI: trying to set non-standard region %s/%d\n",
dev->slot_name, resno);
return;
}
pci_write_config_dword(dev, reg, new);
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & mask) {
printk(KERN_ERR "PCI: Error while updating region "
"%s/%d (%08x != %08x)\n", dev->slot_name, resno,
new, check);
}
if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
(PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) {
new = 0; /* currently everyone zeros the high address */
pci_write_config_dword(dev, reg + 4, new);
pci_read_config_dword(dev, reg + 4, &check);
if (check != new) {
printk(KERN_ERR "PCI: Error updating region "
"%s/%d (high %08x != %08x)\n",
dev->slot_name, resno, new, check);
}
}
}
int __init
pci_claim_resource(struct pci_dev *dev, int resource)
{
......@@ -89,10 +142,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
printk(KERN_ERR "PCI: Failed to allocate resource %d(%lx-%lx) for %s\n",
resno, res->start, res->end, dev->slot_name);
} else {
DBGC((KERN_ERR " got res[%lx:%lx] for resource %d of %s\n",
res->start, res->end, resno, dev->dev.name));
/* Update PCI config space. */
pcibios_update_resource(dev, res, resno);
pci_update_resource(dev, res, resno);
}
return ret;
......
......@@ -529,7 +529,6 @@ char *pcibios_setup (char *str);
/* Used only when drivers/pci/setup.c is used */
void pcibios_align_resource(void *, struct resource *,
unsigned long, unsigned long);
void pcibios_update_resource(struct pci_dev *, struct resource *, int);
void pcibios_update_irq(struct pci_dev *, int irq);
/* Generic PCI functions used internally */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment