aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/pci/i386.c')
-rw-r--r--arch/x86/pci/i386.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index b22d13b0c71d..97da2ba9344b 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -60,22 +60,23 @@ skip_isa_ioresource_align(struct pci_dev *dev) {
60 * but we want to try to avoid allocating at 0x2900-0x2bff 60 * but we want to try to avoid allocating at 0x2900-0x2bff
61 * which might have be mirrored at 0x0100-0x03ff.. 61 * which might have be mirrored at 0x0100-0x03ff..
62 */ 62 */
63void 63resource_size_t
64pcibios_align_resource(void *data, struct resource *res, 64pcibios_align_resource(void *data, const struct resource *res,
65 resource_size_t size, resource_size_t align) 65 resource_size_t size, resource_size_t align)
66{ 66{
67 struct pci_dev *dev = data; 67 struct pci_dev *dev = data;
68 resource_size_t start = res->start;
68 69
69 if (res->flags & IORESOURCE_IO) { 70 if (res->flags & IORESOURCE_IO) {
70 resource_size_t start = res->start;
71
72 if (skip_isa_ioresource_align(dev)) 71 if (skip_isa_ioresource_align(dev))
73 return; 72 return start;
74 if (start & 0x300) { 73 if (start & 0x300)
75 start = (start + 0x3ff) & ~0x3ff; 74 start = (start + 0x3ff) & ~0x3ff;
76 res->start = start; 75 } else if (res->flags & IORESOURCE_MEM) {
77 } 76 if (start < BIOS_END)
77 start = BIOS_END;
78 } 78 }
79 return start;
79} 80}
80EXPORT_SYMBOL(pcibios_align_resource); 81EXPORT_SYMBOL(pcibios_align_resource);
81 82
@@ -129,7 +130,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
129 continue; 130 continue;
130 if (!r->start || 131 if (!r->start ||
131 pci_claim_resource(dev, idx) < 0) { 132 pci_claim_resource(dev, idx) < 0) {
132 dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
133 /* 133 /*
134 * Something is wrong with the region. 134 * Something is wrong with the region.
135 * Invalidate the resource to prevent 135 * Invalidate the resource to prevent
@@ -144,16 +144,29 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
144 } 144 }
145} 145}
146 146
147struct pci_check_idx_range {
148 int start;
149 int end;
150};
151
147static void __init pcibios_allocate_resources(int pass) 152static void __init pcibios_allocate_resources(int pass)
148{ 153{
149 struct pci_dev *dev = NULL; 154 struct pci_dev *dev = NULL;
150 int idx, disabled; 155 int idx, disabled, i;
151 u16 command; 156 u16 command;
152 struct resource *r; 157 struct resource *r;
153 158
159 struct pci_check_idx_range idx_range[] = {
160 { PCI_STD_RESOURCES, PCI_STD_RESOURCE_END },
161#ifdef CONFIG_PCI_IOV
162 { PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END },
163#endif
164 };
165
154 for_each_pci_dev(dev) { 166 for_each_pci_dev(dev) {
155 pci_read_config_word(dev, PCI_COMMAND, &command); 167 pci_read_config_word(dev, PCI_COMMAND, &command);
156 for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { 168 for (i = 0; i < ARRAY_SIZE(idx_range); i++)
169 for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) {
157 r = &dev->resource[idx]; 170 r = &dev->resource[idx];
158 if (r->parent) /* Already allocated */ 171 if (r->parent) /* Already allocated */
159 continue; 172 continue;
@@ -164,12 +177,10 @@ static void __init pcibios_allocate_resources(int pass)
164 else 177 else
165 disabled = !(command & PCI_COMMAND_MEMORY); 178 disabled = !(command & PCI_COMMAND_MEMORY);
166 if (pass == disabled) { 179 if (pass == disabled) {
167 dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n", 180 dev_dbg(&dev->dev,
168 (unsigned long long) r->start, 181 "BAR %d: reserving %pr (d=%d, p=%d)\n",
169 (unsigned long long) r->end, 182 idx, r, disabled, pass);
170 r->flags, disabled, pass);
171 if (pci_claim_resource(dev, idx) < 0) { 183 if (pci_claim_resource(dev, idx) < 0) {
172 dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
173 /* We'll assign a new address later */ 184 /* We'll assign a new address later */
174 r->end -= r->start; 185 r->end -= r->start;
175 r->start = 0; 186 r->start = 0;
@@ -182,7 +193,7 @@ static void __init pcibios_allocate_resources(int pass)
182 /* Turn the ROM off, leave the resource region, 193 /* Turn the ROM off, leave the resource region,
183 * but keep it unregistered. */ 194 * but keep it unregistered. */
184 u32 reg; 195 u32 reg;
185 dev_dbg(&dev->dev, "disabling ROM\n"); 196 dev_dbg(&dev->dev, "disabling ROM %pR\n", r);
186 r->flags &= ~IORESOURCE_ROM_ENABLE; 197 r->flags &= ~IORESOURCE_ROM_ENABLE;
187 pci_read_config_dword(dev, 198 pci_read_config_dword(dev,
188 dev->rom_base_reg, &reg); 199 dev->rom_base_reg, &reg);
@@ -242,10 +253,6 @@ void __init pcibios_resource_survey(void)
242 */ 253 */
243fs_initcall(pcibios_assign_resources); 254fs_initcall(pcibios_assign_resources);
244 255
245void __weak x86_pci_root_bus_res_quirks(struct pci_bus *b)
246{
247}
248
249/* 256/*
250 * If we set up a device for bus mastering, we need to check the latency 257 * If we set up a device for bus mastering, we need to check the latency
251 * timer as certain crappy BIOSes forget to set it properly. 258 * timer as certain crappy BIOSes forget to set it properly.
@@ -282,6 +289,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
282 return -EINVAL; 289 return -EINVAL;
283 290
284 prot = pgprot_val(vma->vm_page_prot); 291 prot = pgprot_val(vma->vm_page_prot);
292
293 /*
294 * Return error if pat is not enabled and write_combine is requested.
295 * Caller can followup with UC MINUS request and add a WC mtrr if there
296 * is a free mtrr slot.
297 */
298 if (!pat_enabled && write_combine)
299 return -EINVAL;
300
285 if (pat_enabled && write_combine) 301 if (pat_enabled && write_combine)
286 prot |= _PAGE_CACHE_WC; 302 prot |= _PAGE_CACHE_WC;
287 else if (pat_enabled || boot_cpu_data.x86 > 3) 303 else if (pat_enabled || boot_cpu_data.x86 > 3)