diff options
Diffstat (limited to 'arch/x86/pci/i386.c')
-rw-r--r-- | arch/x86/pci/i386.c | 58 |
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 | */ |
63 | void | 63 | resource_size_t |
64 | pcibios_align_resource(void *data, struct resource *res, | 64 | pcibios_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 | } |
80 | EXPORT_SYMBOL(pcibios_align_resource); | 81 | EXPORT_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 | ||
147 | struct pci_check_idx_range { | ||
148 | int start; | ||
149 | int end; | ||
150 | }; | ||
151 | |||
147 | static void __init pcibios_allocate_resources(int pass) | 152 | static 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, ®); | 199 | dev->rom_base_reg, ®); |
@@ -242,10 +253,6 @@ void __init pcibios_resource_survey(void) | |||
242 | */ | 253 | */ |
243 | fs_initcall(pcibios_assign_resources); | 254 | fs_initcall(pcibios_assign_resources); |
244 | 255 | ||
245 | void __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) |