Merge branch 'pci/resource' into next
* pci/resource: (26 commits) Revert "[PATCH] Insert GART region into resource map" PCI: Log IDE resource quirk in dmesg PCI: Change pci_bus_alloc_resource() type_mask to unsigned long PCI: Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region() resources: Set type in __request_region() PCI: Don't check resource_size() in pci_bus_alloc_resource() s390/PCI: Use generic pci_enable_resources() tile PCI RC: Use default pcibios_enable_device() sparc/PCI: Use default pcibios_enable_device() (Leon only) sh/PCI: Use default pcibios_enable_device() microblaze/PCI: Use default pcibios_enable_device() alpha/PCI: Use default pcibios_enable_device() PCI: Add "weak" generic pcibios_enable_device() implementation PCI: Don't enable decoding if BAR hasn't been assigned an address PCI: Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit PCI: Don't try to claim IORESOURCE_UNSET resources PCI: Check IORESOURCE_UNSET before updating BAR PCI: Don't clear IORESOURCE_UNSET when updating BAR PCI: Mark resources as IORESOURCE_UNSET if we can't assign them PCI: Remove pci_find_parent_resource() use for allocation ...
This commit is contained in:
commit
30723cbf6f
|
@ -254,12 +254,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we set up a device for bus mastering, we need to check the latency
|
||||
* timer as certain firmware forgets to set it properly, as seen
|
||||
|
|
|
@ -1294,11 +1294,6 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
static void pcibios_setup_phb_resources(struct pci_controller *hose,
|
||||
struct list_head *resources)
|
||||
{
|
||||
|
|
|
@ -686,27 +686,13 @@ int pcibios_add_device(struct pci_dev *pdev)
|
|||
int pcibios_enable_device(struct pci_dev *pdev, int mask)
|
||||
{
|
||||
struct zpci_dev *zdev = get_zdev(pdev);
|
||||
struct resource *res;
|
||||
u16 cmd;
|
||||
int i;
|
||||
|
||||
zdev->pdev = pdev;
|
||||
zpci_debug_init_device(zdev);
|
||||
zpci_fmb_enable_device(zdev);
|
||||
zpci_map_resources(zdev);
|
||||
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
|
||||
for (i = 0; i < PCI_BAR_COUNT; i++) {
|
||||
res = &pdev->resource[i];
|
||||
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
return -EINVAL;
|
||||
|
||||
if (res->flags & IORESOURCE_MEM)
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
}
|
||||
pci_write_config_word(pdev, PCI_COMMAND, cmd);
|
||||
return 0;
|
||||
return pci_enable_resources(pdev, mask);
|
||||
}
|
||||
|
||||
void pcibios_disable_device(struct pci_dev *pdev)
|
||||
|
|
|
@ -186,11 +186,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
|
|||
return start;
|
||||
}
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
static void __init
|
||||
pcibios_bus_report_status_early(struct pci_channel *hose,
|
||||
int top_bus, int current_bus,
|
||||
|
|
|
@ -99,11 +99,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
|
|||
return res->start;
|
||||
}
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
/* in/out routines taken from pcic.c
|
||||
*
|
||||
* This probably belongs here rather than ioport.c because
|
||||
|
|
|
@ -1064,18 +1064,6 @@ char *__init pcibios_setup(char *str)
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable memory address decoding, as appropriate, for the
|
||||
* device described by the 'dev' struct.
|
||||
*
|
||||
* This is called from the generic PCI layer, and can be called
|
||||
* for bridges or endpoints.
|
||||
*/
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for each device after PCI setup is done.
|
||||
* We initialize the PCI device capabilities conservatively, assuming that
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <linux/pci_ids.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -54,18 +53,6 @@ int fallback_aper_force __initdata;
|
|||
|
||||
int fix_aperture __initdata = 1;
|
||||
|
||||
static struct resource gart_resource = {
|
||||
.name = "GART",
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
|
||||
{
|
||||
gart_resource.start = aper_base;
|
||||
gart_resource.end = aper_base + aper_size - 1;
|
||||
insert_resource(&iomem_resource, &gart_resource);
|
||||
}
|
||||
|
||||
/* This code runs before the PCI subsystem is initialized, so just
|
||||
access the northbridge directly. */
|
||||
|
||||
|
@ -96,7 +83,6 @@ static u32 __init allocate_aperture(void)
|
|||
memblock_reserve(addr, aper_size);
|
||||
printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n",
|
||||
aper_size >> 10, addr);
|
||||
insert_aperture_resource((u32)addr, aper_size);
|
||||
register_nosave_region(addr >> PAGE_SHIFT,
|
||||
(addr+aper_size) >> PAGE_SHIFT);
|
||||
|
||||
|
@ -444,12 +430,8 @@ int __init gart_iommu_hole_init(void)
|
|||
|
||||
out:
|
||||
if (!fix && !fallback_aper_force) {
|
||||
if (last_aper_base) {
|
||||
unsigned long n = (32 * 1024 * 1024) << last_aper_order;
|
||||
|
||||
insert_aperture_resource((u32)last_aper_base, n);
|
||||
if (last_aper_base)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -652,6 +652,44 @@ static int i2o_iop_activate(struct i2o_controller *c)
|
|||
return i2o_hrt_get(c);
|
||||
};
|
||||
|
||||
static void i2o_res_alloc(struct i2o_controller *c, unsigned long flags)
|
||||
{
|
||||
i2o_status_block *sb = c->status_block.virt;
|
||||
struct resource *res = &c->mem_resource;
|
||||
resource_size_t size, align;
|
||||
int err;
|
||||
|
||||
res->name = c->pdev->bus->name;
|
||||
res->flags = flags;
|
||||
res->start = 0;
|
||||
res->end = 0;
|
||||
osm_info("%s: requires private memory resources.\n", c->name);
|
||||
|
||||
if (flags & IORESOURCE_MEM) {
|
||||
size = sb->desired_mem_size;
|
||||
align = 1 << 20; /* unspecified, use 1Mb and play safe */
|
||||
} else {
|
||||
size = sb->desired_io_size;
|
||||
align = 1 << 12; /* unspecified, use 4Kb and play safe */
|
||||
}
|
||||
|
||||
err = pci_bus_alloc_resource(c->pdev->bus, res, size, align, 0, 0,
|
||||
NULL, NULL);
|
||||
if (err < 0)
|
||||
return;
|
||||
|
||||
if (flags & IORESOURCE_MEM) {
|
||||
c->mem_alloc = 1;
|
||||
sb->current_mem_size = resource_size(res);
|
||||
sb->current_mem_base = res->start;
|
||||
} else if (flags & IORESOURCE_IO) {
|
||||
c->io_alloc = 1;
|
||||
sb->current_io_size = resource_size(res);
|
||||
sb->current_io_base = res->start;
|
||||
}
|
||||
osm_info("%s: allocated PCI space %pR\n", c->name, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* i2o_iop_systab_set - Set the I2O System Table of the specified IOP
|
||||
* @c: I2O controller to which the system table should be send
|
||||
|
@ -665,52 +703,13 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
|
|||
struct i2o_message *msg;
|
||||
i2o_status_block *sb = c->status_block.virt;
|
||||
struct device *dev = &c->pdev->dev;
|
||||
struct resource *root;
|
||||
int rc;
|
||||
|
||||
if (sb->current_mem_size < sb->desired_mem_size) {
|
||||
struct resource *res = &c->mem_resource;
|
||||
res->name = c->pdev->bus->name;
|
||||
res->flags = IORESOURCE_MEM;
|
||||
res->start = 0;
|
||||
res->end = 0;
|
||||
osm_info("%s: requires private memory resources.\n", c->name);
|
||||
root = pci_find_parent_resource(c->pdev, res);
|
||||
if (root == NULL)
|
||||
osm_warn("%s: Can't find parent resource!\n", c->name);
|
||||
if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
|
||||
NULL, NULL) >= 0) {
|
||||
c->mem_alloc = 1;
|
||||
sb->current_mem_size = resource_size(res);
|
||||
sb->current_mem_base = res->start;
|
||||
osm_info("%s: allocated %llu bytes of PCI memory at "
|
||||
"0x%016llX.\n", c->name,
|
||||
(unsigned long long)resource_size(res),
|
||||
(unsigned long long)res->start);
|
||||
}
|
||||
}
|
||||
if (sb->current_mem_size < sb->desired_mem_size)
|
||||
i2o_res_alloc(c, IORESOURCE_MEM);
|
||||
|
||||
if (sb->current_io_size < sb->desired_io_size) {
|
||||
struct resource *res = &c->io_resource;
|
||||
res->name = c->pdev->bus->name;
|
||||
res->flags = IORESOURCE_IO;
|
||||
res->start = 0;
|
||||
res->end = 0;
|
||||
osm_info("%s: requires private memory resources.\n", c->name);
|
||||
root = pci_find_parent_resource(c->pdev, res);
|
||||
if (root == NULL)
|
||||
osm_warn("%s: Can't find parent resource!\n", c->name);
|
||||
if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
|
||||
NULL, NULL) >= 0) {
|
||||
c->io_alloc = 1;
|
||||
sb->current_io_size = resource_size(res);
|
||||
sb->current_mem_base = res->start;
|
||||
osm_info("%s: allocated %llu bytes of PCI I/O at "
|
||||
"0x%016llX.\n", c->name,
|
||||
(unsigned long long)resource_size(res),
|
||||
(unsigned long long)res->start);
|
||||
}
|
||||
}
|
||||
if (sb->current_io_size < sb->desired_io_size)
|
||||
i2o_res_alloc(c, IORESOURCE_IO);
|
||||
|
||||
msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
|
||||
if (IS_ERR(msg))
|
||||
|
|
|
@ -132,7 +132,7 @@ static void pci_clip_resource_to_region(struct pci_bus *bus,
|
|||
|
||||
static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
||||
resource_size_t size, resource_size_t align,
|
||||
resource_size_t min, unsigned int type_mask,
|
||||
resource_size_t min, unsigned long type_mask,
|
||||
resource_size_t (*alignf)(void *,
|
||||
const struct resource *,
|
||||
resource_size_t,
|
||||
|
@ -144,7 +144,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
|||
struct resource *r, avail;
|
||||
resource_size_t max;
|
||||
|
||||
type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
|
||||
type_mask |= IORESOURCE_TYPE_BITS;
|
||||
|
||||
pci_bus_for_each_resource(bus, r, i) {
|
||||
if (!r)
|
||||
|
@ -162,8 +162,6 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
|||
|
||||
avail = *r;
|
||||
pci_clip_resource_to_region(bus, &avail, region);
|
||||
if (!resource_size(&avail))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to
|
||||
|
@ -202,7 +200,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
|||
*/
|
||||
int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
|
||||
resource_size_t size, resource_size_t align,
|
||||
resource_size_t min, unsigned int type_mask,
|
||||
resource_size_t min, unsigned long type_mask,
|
||||
resource_size_t (*alignf)(void *,
|
||||
const struct resource *,
|
||||
resource_size_t,
|
||||
|
|
|
@ -32,11 +32,6 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
|
|||
bridge->release_data = release_data;
|
||||
}
|
||||
|
||||
static bool resource_contains(struct resource *res1, struct resource *res2)
|
||||
{
|
||||
return res1->start <= res2->start && res1->end >= res2->end;
|
||||
}
|
||||
|
||||
void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
|
||||
struct resource *res)
|
||||
{
|
||||
|
@ -45,9 +40,6 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
|
|||
resource_size_t offset = 0;
|
||||
|
||||
list_for_each_entry(window, &bridge->windows, list) {
|
||||
if (resource_type(res) != resource_type(window->res))
|
||||
continue;
|
||||
|
||||
if (resource_contains(window->res, res)) {
|
||||
offset = window->offset;
|
||||
break;
|
||||
|
|
|
@ -401,33 +401,40 @@ EXPORT_SYMBOL_GPL(pci_find_ht_capability);
|
|||
* @res: child resource record for which parent is sought
|
||||
*
|
||||
* For given resource region of given device, return the resource
|
||||
* region of parent bus the given region is contained in or where
|
||||
* it should be allocated from.
|
||||
* region of parent bus the given region is contained in.
|
||||
*/
|
||||
struct resource *
|
||||
pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
|
||||
{
|
||||
const struct pci_bus *bus = dev->bus;
|
||||
struct resource *r;
|
||||
int i;
|
||||
struct resource *best = NULL, *r;
|
||||
|
||||
pci_bus_for_each_resource(bus, r, i) {
|
||||
if (!r)
|
||||
continue;
|
||||
if (res->start && !(res->start >= r->start && res->end <= r->end))
|
||||
continue; /* Not contained */
|
||||
if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
|
||||
continue; /* Wrong type */
|
||||
if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
|
||||
return r; /* Exact match */
|
||||
/* We can't insert a non-prefetch resource inside a prefetchable parent .. */
|
||||
if (r->flags & IORESOURCE_PREFETCH)
|
||||
continue;
|
||||
/* .. but we can put a prefetchable resource inside a non-prefetchable one */
|
||||
if (!best)
|
||||
best = r;
|
||||
if (res->start && resource_contains(r, res)) {
|
||||
|
||||
/*
|
||||
* If the window is prefetchable but the BAR is
|
||||
* not, the allocator made a mistake.
|
||||
*/
|
||||
if (r->flags & IORESOURCE_PREFETCH &&
|
||||
!(res->flags & IORESOURCE_PREFETCH))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If we're below a transparent bridge, there may
|
||||
* be both a positively-decoded aperture and a
|
||||
* subtractively-decoded region that contain the BAR.
|
||||
* We want the positively-decoded one, so this depends
|
||||
* on pci_bus_for_each_resource() giving us those
|
||||
* first.
|
||||
*/
|
||||
return r;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1178,6 +1185,11 @@ int pci_load_and_free_saved_state(struct pci_dev *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
|
||||
|
||||
int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
|
||||
{
|
||||
return pci_enable_resources(dev, bars);
|
||||
}
|
||||
|
||||
static int do_pci_enable_device(struct pci_dev *dev, int bars)
|
||||
{
|
||||
int err;
|
||||
|
@ -4262,6 +4274,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
|
|||
"Rounding up size of resource #%d to %#llx.\n",
|
||||
i, (unsigned long long)size);
|
||||
}
|
||||
r->flags |= IORESOURCE_UNSET;
|
||||
r->end = size - 1;
|
||||
r->start = 0;
|
||||
}
|
||||
|
@ -4275,6 +4288,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
|
|||
r = &dev->resource[i];
|
||||
if (!(r->flags & IORESOURCE_MEM))
|
||||
continue;
|
||||
r->flags |= IORESOURCE_UNSET;
|
||||
r->end = resource_size(r) - 1;
|
||||
r->start = 0;
|
||||
}
|
||||
|
|
|
@ -252,6 +252,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
|||
/* Address above 32-bit boundary; disable the BAR */
|
||||
pci_write_config_dword(dev, pos, 0);
|
||||
pci_write_config_dword(dev, pos + 4, 0);
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
region.start = 0;
|
||||
region.end = sz64;
|
||||
bar_disabled = true;
|
||||
|
@ -1121,11 +1122,15 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
res = &dev->resource[0];
|
||||
res->flags = LEGACY_IO_RESOURCE;
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
dev_info(&dev->dev, "legacy IDE quirk: reg 0x10: %pR\n",
|
||||
res);
|
||||
region.start = 0x3F6;
|
||||
region.end = 0x3F6;
|
||||
res = &dev->resource[1];
|
||||
res->flags = LEGACY_IO_RESOURCE;
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
dev_info(&dev->dev, "legacy IDE quirk: reg 0x14: %pR\n",
|
||||
res);
|
||||
}
|
||||
if ((progif & 4) == 0) {
|
||||
region.start = 0x170;
|
||||
|
@ -1133,11 +1138,15 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
res = &dev->resource[2];
|
||||
res->flags = LEGACY_IO_RESOURCE;
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
dev_info(&dev->dev, "legacy IDE quirk: reg 0x18: %pR\n",
|
||||
res);
|
||||
region.start = 0x376;
|
||||
region.end = 0x376;
|
||||
res = &dev->resource[3];
|
||||
res->flags = LEGACY_IO_RESOURCE;
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
dev_info(&dev->dev, "legacy IDE quirk: reg 0x1c: %pR\n",
|
||||
res);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -296,6 +296,7 @@ static void quirk_s3_64M(struct pci_dev *dev)
|
|||
struct resource *r = &dev->resource[0];
|
||||
|
||||
if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) {
|
||||
r->flags |= IORESOURCE_UNSET;
|
||||
r->start = 0;
|
||||
r->end = 0x3ffffff;
|
||||
}
|
||||
|
@ -937,6 +938,8 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C
|
|||
static void quirk_dunord(struct pci_dev *dev)
|
||||
{
|
||||
struct resource *r = &dev->resource [1];
|
||||
|
||||
r->flags |= IORESOURCE_UNSET;
|
||||
r->start = 0;
|
||||
r->end = 0xffffff;
|
||||
}
|
||||
|
@ -1740,6 +1743,7 @@ static void quirk_tc86c001_ide(struct pci_dev *dev)
|
|||
struct resource *r = &dev->resource[0];
|
||||
|
||||
if (r->start & 0x8) {
|
||||
r->flags |= IORESOURCE_UNSET;
|
||||
r->start = 0;
|
||||
r->end = 0xf;
|
||||
}
|
||||
|
@ -1769,6 +1773,7 @@ static void quirk_plx_pci9050(struct pci_dev *dev)
|
|||
dev_info(&dev->dev,
|
||||
"Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
|
||||
bar);
|
||||
r->flags |= IORESOURCE_UNSET;
|
||||
r->start = 0;
|
||||
r->end = 0xff;
|
||||
}
|
||||
|
|
|
@ -197,8 +197,10 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
|
|||
void pci_cleanup_rom(struct pci_dev *pdev)
|
||||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
|
||||
if (res->flags & IORESOURCE_ROM_COPY) {
|
||||
kfree((void*)(unsigned long)res->start);
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
res->flags &= ~IORESOURCE_ROM_COPY;
|
||||
res->start = 0;
|
||||
res->end = 0;
|
||||
|
|
|
@ -44,6 +44,9 @@ void pci_update_resource(struct pci_dev *dev, int resno)
|
|||
if (!res->flags)
|
||||
return;
|
||||
|
||||
if (res->flags & IORESOURCE_UNSET)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Ignore non-moveable resources. This might be legacy resources for
|
||||
* which no functional BAR register exists or another important
|
||||
|
@ -101,11 +104,6 @@ void pci_update_resource(struct pci_dev *dev, int resno)
|
|||
|
||||
if (disable)
|
||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
|
||||
resno, res, (unsigned long long)region.start,
|
||||
(unsigned long long)region.end);
|
||||
}
|
||||
|
||||
int pci_claim_resource(struct pci_dev *dev, int resource)
|
||||
|
@ -113,18 +111,23 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
|
|||
struct resource *res = &dev->resource[resource];
|
||||
struct resource *root, *conflict;
|
||||
|
||||
if (res->flags & IORESOURCE_UNSET) {
|
||||
dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n",
|
||||
resource, res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
root = pci_find_parent_resource(dev, res);
|
||||
if (!root) {
|
||||
dev_info(&dev->dev, "no compatible bridge window for %pR\n",
|
||||
res);
|
||||
dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
|
||||
resource, res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
conflict = request_resource_conflict(root, res);
|
||||
if (conflict) {
|
||||
dev_info(&dev->dev,
|
||||
"address space collision: %pR conflicts with %s %pR\n",
|
||||
res, conflict->name, conflict);
|
||||
dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
|
||||
resource, res, conflict->name, conflict);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -263,6 +266,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
|
|||
resource_size_t align, size;
|
||||
int ret;
|
||||
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
align = pci_resource_alignment(dev, res);
|
||||
if (!align) {
|
||||
dev_info(&dev->dev, "BAR %d: can't assign %pR "
|
||||
|
@ -282,6 +286,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
|
|||
ret = pci_revert_fw_address(res, dev, resno, size);
|
||||
|
||||
if (!ret) {
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
res->flags &= ~IORESOURCE_STARTALIGN;
|
||||
dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
|
||||
if (resno < PCI_BRIDGE_RESOURCES)
|
||||
|
@ -297,6 +302,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
|
|||
resource_size_t new_size;
|
||||
int ret;
|
||||
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
if (!res->parent) {
|
||||
dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR "
|
||||
"\n", resno, res);
|
||||
|
@ -307,6 +313,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
|
|||
new_size = resource_size(res) + addsize;
|
||||
ret = _pci_assign_resource(dev, resno, new_size, min_align);
|
||||
if (!ret) {
|
||||
res->flags &= ~IORESOURCE_UNSET;
|
||||
res->flags &= ~IORESOURCE_STARTALIGN;
|
||||
dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
|
||||
if (resno < PCI_BRIDGE_RESOURCES)
|
||||
|
@ -336,9 +343,15 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
|
|||
(!(r->flags & IORESOURCE_ROM_ENABLE)))
|
||||
continue;
|
||||
|
||||
if (r->flags & IORESOURCE_UNSET) {
|
||||
dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n",
|
||||
i, r);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!r->parent) {
|
||||
dev_err(&dev->dev, "device not available "
|
||||
"(can't reserve %pR)\n", r);
|
||||
dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n",
|
||||
i, r);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ struct resource {
|
|||
|
||||
#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */
|
||||
#define IORESOURCE_DISABLED 0x10000000
|
||||
#define IORESOURCE_UNSET 0x20000000
|
||||
#define IORESOURCE_UNSET 0x20000000 /* No address assigned yet */
|
||||
#define IORESOURCE_AUTO 0x40000000
|
||||
#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */
|
||||
|
||||
|
@ -169,6 +169,16 @@ static inline unsigned long resource_type(const struct resource *res)
|
|||
{
|
||||
return res->flags & IORESOURCE_TYPE_BITS;
|
||||
}
|
||||
/* True iff r1 completely contains r2 */
|
||||
static inline bool resource_contains(struct resource *r1, struct resource *r2)
|
||||
{
|
||||
if (resource_type(r1) != resource_type(r2))
|
||||
return false;
|
||||
if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET)
|
||||
return false;
|
||||
return r1->start <= r2->start && r1->end >= r2->end;
|
||||
}
|
||||
|
||||
|
||||
/* Convenience shorthand with allocation */
|
||||
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0)
|
||||
|
|
|
@ -1066,7 +1066,7 @@ void pci_bus_remove_resources(struct pci_bus *bus);
|
|||
int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
|
||||
struct resource *res, resource_size_t size,
|
||||
resource_size_t align, resource_size_t min,
|
||||
unsigned int type_mask,
|
||||
unsigned long type_mask,
|
||||
resource_size_t (*alignf)(void *,
|
||||
const struct resource *,
|
||||
resource_size_t,
|
||||
|
|
|
@ -432,11 +432,6 @@ static void resource_clip(struct resource *res, resource_size_t min,
|
|||
res->end = max;
|
||||
}
|
||||
|
||||
static bool resource_contains(struct resource *res1, struct resource *res2)
|
||||
{
|
||||
return res1->start <= res2->start && res1->end >= res2->end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find empty slot in the resource tree with the given range and
|
||||
* alignment constraints
|
||||
|
@ -471,10 +466,11 @@ static int __find_resource(struct resource *root, struct resource *old,
|
|||
arch_remove_reservations(&tmp);
|
||||
|
||||
/* Check for overflow after ALIGN() */
|
||||
avail = *new;
|
||||
avail.start = ALIGN(tmp.start, constraint->align);
|
||||
avail.end = tmp.end;
|
||||
avail.flags = new->flags & ~IORESOURCE_UNSET;
|
||||
if (avail.start >= tmp.start) {
|
||||
alloc.flags = avail.flags;
|
||||
alloc.start = constraint->alignf(constraint->alignf_data, &avail,
|
||||
size, constraint->align);
|
||||
alloc.end = alloc.start + size - 1;
|
||||
|
@ -949,8 +945,8 @@ struct resource * __request_region(struct resource *parent,
|
|||
res->name = name;
|
||||
res->start = start;
|
||||
res->end = start + n - 1;
|
||||
res->flags = IORESOURCE_BUSY;
|
||||
res->flags |= flags;
|
||||
res->flags = resource_type(parent);
|
||||
res->flags |= IORESOURCE_BUSY | flags;
|
||||
|
||||
write_lock(&resource_lock);
|
||||
|
||||
|
|
|
@ -719,11 +719,16 @@ char *resource_string(char *buf, char *end, struct resource *res,
|
|||
specp = &mem_spec;
|
||||
decode = 0;
|
||||
}
|
||||
if (decode && res->flags & IORESOURCE_UNSET) {
|
||||
p = string(p, pend, "size ", str_spec);
|
||||
p = number(p, pend, resource_size(res), *specp);
|
||||
} else {
|
||||
p = number(p, pend, res->start, *specp);
|
||||
if (res->start != res->end) {
|
||||
*p++ = '-';
|
||||
p = number(p, pend, res->end, *specp);
|
||||
}
|
||||
}
|
||||
if (decode) {
|
||||
if (res->flags & IORESOURCE_MEM_64)
|
||||
p = string(p, pend, " 64bit", str_spec);
|
||||
|
|
Loading…
Reference in a new issue