Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 91692
b: refs/heads/master
c: 8845256
h: refs/heads/master
v: v3
  • Loading branch information
Ivan Kokshaysky authored and Greg Kroah-Hartman committed Apr 21, 2008
1 parent c6a4a6d commit 8d2678a
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d75b305295c38ba9610ff3b2200f7d1989dc55fd
refs/heads/master: 884525655d07fdee9245716b998ecdc45cdd8007
5 changes: 3 additions & 2 deletions trunk/drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
}
res->end = res->start + (unsigned long) sz;
res->flags |= pci_calc_resource_flags(l);
res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
if (is_64bit_memory(l)) {
u32 szhi, lhi;

Expand Down Expand Up @@ -288,7 +288,8 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
if (sz) {
res->flags = (l & IORESOURCE_ROM_ENABLE) |
IORESOURCE_MEM | IORESOURCE_PREFETCH |
IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
IORESOURCE_SIZEALIGN;
res->start = l & PCI_ROM_ADDRESS_MASK;
res->end = res->start + (unsigned long) sz;
}
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/pci/setup-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ static void pbus_assign_resources_sorted(struct pci_bus *bus)
res = list->res;
idx = res - &list->dev->resource[0];
if (pci_assign_resource(list->dev, idx)) {
/* FIXME: get rid of this */
res->start = 0;
res->end = 0;
res->flags = 0;
Expand Down Expand Up @@ -327,6 +328,7 @@ static void pbus_size_io(struct pci_bus *bus)
/* Alignment of the IO window is always 4K */
b_res->start = 4096;
b_res->end = b_res->start + size - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
}

/* Calculate the size of the bus and minimal alignment which
Expand Down Expand Up @@ -401,6 +403,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
}
b_res->start = min_align;
b_res->end = size + min_align - 1;
b_res->flags |= IORESOURCE_STARTALIGN;
return 1;
}

Expand Down
42 changes: 23 additions & 19 deletions trunk/drivers/pci/setup-res.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,16 @@ int pci_assign_resource(struct pci_dev *dev, int resno)

size = res->end - res->start + 1;
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
/* The bridge resources are special, as their
size != alignment. Sizing routines return
required alignment in the "start" field. */
align = (resno < PCI_BRIDGE_RESOURCES) ? size : res->start;

align = resource_alignment(res);
if (!align) {
printk(KERN_ERR "PCI: Cannot allocate resource (bogus "
"alignment) %d [%llx:%llx] (flags %lx) of %s\n",
resno, (unsigned long long)res->start,
(unsigned long long)res->end, res->flags,
pci_name(dev));
return -EINVAL;
}

/* First, try exact prefetching match.. */
ret = pci_bus_alloc_resource(bus, res, size, align, min,
Expand All @@ -164,8 +170,10 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
res->flags & IORESOURCE_IO ? "I/O" : "mem",
resno, (unsigned long long)size,
(unsigned long long)res->start, pci_name(dev));
} else if (resno < PCI_BRIDGE_RESOURCES) {
pci_update_resource(dev, res, resno);
} else {
res->flags &= ~IORESOURCE_STARTALIGN;
if (resno < PCI_BRIDGE_RESOURCES)
pci_update_resource(dev, res, resno);
}

return ret;
Expand Down Expand Up @@ -226,29 +234,25 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
if (r->flags & IORESOURCE_PCI_FIXED)
continue;

r_align = r->end - r->start;

if (!(r->flags) || r->parent)
continue;

r_align = resource_alignment(r);
if (!r_align) {
printk(KERN_WARNING "PCI: Ignore bogus resource %d "
"[%llx:%llx] of %s\n",
printk(KERN_WARNING "PCI: bogus alignment of resource "
"%d [%llx:%llx] (flags %lx) of %s\n",
i, (unsigned long long)r->start,
(unsigned long long)r->end, pci_name(dev));
(unsigned long long)r->end, r->flags,
pci_name(dev));
continue;
}
r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
for (list = head; ; list = list->next) {
resource_size_t align = 0;
struct resource_list *ln = list->next;
int idx;

if (ln) {
idx = ln->res - &ln->dev->resource[0];
align = (idx < PCI_BRIDGE_RESOURCES) ?
ln->res->end - ln->res->start + 1 :
ln->res->start;
}
if (ln)
align = resource_alignment(ln->res);

if (r_align > align) {
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp)
Expand Down
5 changes: 4 additions & 1 deletion trunk/include/linux/ioport.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ struct resource_list {
#define IORESOURCE_CACHEABLE 0x00004000
#define IORESOURCE_RANGELENGTH 0x00008000
#define IORESOURCE_SHADOWABLE 0x00010000
#define IORESOURCE_BUS_HAS_VGA 0x00080000

#define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */
#define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */

#define IORESOURCE_DISABLED 0x10000000
#define IORESOURCE_UNSET 0x20000000
Expand Down Expand Up @@ -110,6 +112,7 @@ extern int allocate_resource(struct resource *root, struct resource *new,
void *alignf_data);
int adjust_resource(struct resource *res, resource_size_t start,
resource_size_t size);
resource_size_t resource_alignment(struct resource *res);

/* Convenience shorthand with allocation */
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
Expand Down
18 changes: 18 additions & 0 deletions trunk/kernel/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,24 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t

EXPORT_SYMBOL(adjust_resource);

/**
* resource_alignment - calculate resource's alignment
* @res: resource pointer
*
* Returns alignment on success, 0 (invalid alignment) on failure.
*/
resource_size_t resource_alignment(struct resource *res)
{
switch (res->flags & (IORESOURCE_SIZEALIGN | IORESOURCE_STARTALIGN)) {
case IORESOURCE_SIZEALIGN:
return res->end - res->start + 1;
case IORESOURCE_STARTALIGN:
return res->start;
default:
return 0;
}
}

/*
* This is compatibility stuff for IO resources.
*
Expand Down

0 comments on commit 8d2678a

Please sign in to comment.