41 lines
1.2 KiB
Diff
41 lines
1.2 KiB
Diff
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
|
|
index 5525309..fe866c8 100644
|
|
--- a/arch/x86/pci/i386.c
|
|
+++ b/arch/x86/pci/i386.c
|
|
@@ -37,6 +37,7 @@
|
|
#include <asm/pci_x86.h>
|
|
#include <asm/io_apic.h>
|
|
|
|
+#define ALIGN_DOWN(x, a) ((x) & ~(a - 1))
|
|
|
|
static int
|
|
skip_isa_ioresource_align(struct pci_dev *dev) {
|
|
@@ -65,16 +66,21 @@ pcibios_align_resource(void *data, const struct resource *res,
|
|
resource_size_t size, resource_size_t align)
|
|
{
|
|
struct pci_dev *dev = data;
|
|
- resource_size_t start = res->start;
|
|
+ resource_size_t start = ALIGN_DOWN(res->end - size + 1, align);
|
|
|
|
if (res->flags & IORESOURCE_IO) {
|
|
- if (skip_isa_ioresource_align(dev))
|
|
- return start;
|
|
- if (start & 0x300)
|
|
- start = (start + 0x3ff) & ~0x3ff;
|
|
+
|
|
+ /*
|
|
+ * If we're avoiding ISA aliases, the largest contiguous I/O
|
|
+ * port space is 256 bytes. Clearing bits 9 and 10 preserves
|
|
+ * all 256-byte and smaller alignments, so the result will
|
|
+ * still be correctly aligned.
|
|
+ */
|
|
+ if (!skip_isa_ioresource_align(dev))
|
|
+ start &= ~0x300;
|
|
} else if (res->flags & IORESOURCE_MEM) {
|
|
if (start < BIOS_END)
|
|
- start = BIOS_END;
|
|
+ start = res->end; /* fail; no space */
|
|
}
|
|
return start;
|
|
}
|