diff options
-rw-r--r-- | arch/ia64/pci/fixup.c | 21 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_acpi_init.c | 22 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 51 | ||||
-rw-r--r-- | arch/mips/pci/fixup-loongson3.c | 19 | ||||
-rw-r--r-- | arch/x86/pci/fixup.c | 28 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 72 | ||||
-rw-r--r-- | drivers/pci/probe.c | 14 | ||||
-rw-r--r-- | drivers/pci/remove.c | 1 | ||||
-rw-r--r-- | drivers/pci/rom.c | 83 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 6 | ||||
-rw-r--r-- | include/linux/ioport.h | 4 | ||||
-rw-r--r-- | include/linux/pci.h | 1 |
12 files changed, 162 insertions, 160 deletions
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c index fc505d58f078..41caa99add51 100644 --- a/arch/ia64/pci/fixup.c +++ b/arch/ia64/pci/fixup.c | |||
@@ -17,14 +17,14 @@ | |||
17 | * | 17 | * |
18 | * The standard boot ROM sequence for an x86 machine uses the BIOS | 18 | * The standard boot ROM sequence for an x86 machine uses the BIOS |
19 | * to select an initial video card for boot display. This boot video | 19 | * to select an initial video card for boot display. This boot video |
20 | * card will have it's BIOS copied to C0000 in system RAM. | 20 | * card will have its BIOS copied to 0xC0000 in system RAM. |
21 | * IORESOURCE_ROM_SHADOW is used to associate the boot video | 21 | * IORESOURCE_ROM_SHADOW is used to associate the boot video |
22 | * card with this copy. On laptops this copy has to be used since | 22 | * card with this copy. On laptops this copy has to be used since |
23 | * the main ROM may be compressed or combined with another image. | 23 | * the main ROM may be compressed or combined with another image. |
24 | * See pci_map_rom() for use of this flag. Before marking the device | 24 | * See pci_map_rom() for use of this flag. Before marking the device |
25 | * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set | 25 | * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set |
26 | * by either arch cde or vga-arbitration, if so only apply the fixup to this | 26 | * by either arch code or vga-arbitration; if so only apply the fixup to this |
27 | * already determined primary video card. | 27 | * already-determined primary video card. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | static void pci_fixup_video(struct pci_dev *pdev) | 30 | static void pci_fixup_video(struct pci_dev *pdev) |
@@ -32,6 +32,7 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
32 | struct pci_dev *bridge; | 32 | struct pci_dev *bridge; |
33 | struct pci_bus *bus; | 33 | struct pci_bus *bus; |
34 | u16 config; | 34 | u16 config; |
35 | struct resource *res; | ||
35 | 36 | ||
36 | if ((strcmp(ia64_platform_name, "dig") != 0) | 37 | if ((strcmp(ia64_platform_name, "dig") != 0) |
37 | && (strcmp(ia64_platform_name, "hpzx1") != 0)) | 38 | && (strcmp(ia64_platform_name, "hpzx1") != 0)) |
@@ -61,8 +62,18 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
61 | if (!vga_default_device() || pdev == vga_default_device()) { | 62 | if (!vga_default_device() || pdev == vga_default_device()) { |
62 | pci_read_config_word(pdev, PCI_COMMAND, &config); | 63 | pci_read_config_word(pdev, PCI_COMMAND, &config); |
63 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | 64 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { |
64 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | 65 | res = &pdev->resource[PCI_ROM_RESOURCE]; |
65 | dev_printk(KERN_DEBUG, &pdev->dev, "Video device with shadowed ROM\n"); | 66 | |
67 | pci_disable_rom(pdev); | ||
68 | if (res->parent) | ||
69 | release_resource(res); | ||
70 | |||
71 | res->start = 0xC0000; | ||
72 | res->end = res->start + 0x20000 - 1; | ||
73 | res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW | | ||
74 | IORESOURCE_PCI_FIXED; | ||
75 | dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n", | ||
76 | res); | ||
66 | } | 77 | } |
67 | } | 78 | } |
68 | } | 79 | } |
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index 0640739cc20c..231234c8d113 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c | |||
@@ -429,7 +429,8 @@ sn_acpi_slot_fixup(struct pci_dev *dev) | |||
429 | void __iomem *addr; | 429 | void __iomem *addr; |
430 | struct pcidev_info *pcidev_info = NULL; | 430 | struct pcidev_info *pcidev_info = NULL; |
431 | struct sn_irq_info *sn_irq_info = NULL; | 431 | struct sn_irq_info *sn_irq_info = NULL; |
432 | size_t image_size, size; | 432 | struct resource *res; |
433 | size_t size; | ||
433 | 434 | ||
434 | if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) { | 435 | if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) { |
435 | panic("%s: Failure obtaining pcidev_info for %s\n", | 436 | panic("%s: Failure obtaining pcidev_info for %s\n", |
@@ -443,17 +444,20 @@ sn_acpi_slot_fixup(struct pci_dev *dev) | |||
443 | * of the shadowed copy, and the actual length of the ROM image. | 444 | * of the shadowed copy, and the actual length of the ROM image. |
444 | */ | 445 | */ |
445 | size = pci_resource_len(dev, PCI_ROM_RESOURCE); | 446 | size = pci_resource_len(dev, PCI_ROM_RESOURCE); |
446 | addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], | 447 | |
447 | size); | 448 | res = &dev->resource[PCI_ROM_RESOURCE]; |
448 | image_size = pci_get_rom_size(dev, addr, size); | 449 | |
449 | dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; | 450 | pci_disable_rom(dev); |
450 | dev->resource[PCI_ROM_RESOURCE].end = | 451 | if (res->parent) |
451 | (unsigned long) addr + image_size - 1; | 452 | release_resource(res); |
452 | dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY; | 453 | |
454 | res->start = pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]; | ||
455 | res->end = res->start + size - 1; | ||
456 | res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW | | ||
457 | IORESOURCE_PCI_FIXED; | ||
453 | } | 458 | } |
454 | sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); | 459 | sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); |
455 | } | 460 | } |
456 | |||
457 | EXPORT_SYMBOL(sn_acpi_slot_fixup); | 461 | EXPORT_SYMBOL(sn_acpi_slot_fixup); |
458 | 462 | ||
459 | 463 | ||
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 1be65eb074ec..c15a41e2d1f2 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -150,7 +150,8 @@ void | |||
150 | sn_io_slot_fixup(struct pci_dev *dev) | 150 | sn_io_slot_fixup(struct pci_dev *dev) |
151 | { | 151 | { |
152 | int idx; | 152 | int idx; |
153 | unsigned long addr, end, size, start; | 153 | struct resource *res; |
154 | unsigned long addr, size; | ||
154 | struct pcidev_info *pcidev_info; | 155 | struct pcidev_info *pcidev_info; |
155 | struct sn_irq_info *sn_irq_info; | 156 | struct sn_irq_info *sn_irq_info; |
156 | int status; | 157 | int status; |
@@ -175,55 +176,41 @@ sn_io_slot_fixup(struct pci_dev *dev) | |||
175 | 176 | ||
176 | /* Copy over PIO Mapped Addresses */ | 177 | /* Copy over PIO Mapped Addresses */ |
177 | for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { | 178 | for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { |
178 | 179 | if (!pcidev_info->pdi_pio_mapped_addr[idx]) | |
179 | if (!pcidev_info->pdi_pio_mapped_addr[idx]) { | ||
180 | continue; | 180 | continue; |
181 | } | ||
182 | 181 | ||
183 | start = dev->resource[idx].start; | 182 | res = &dev->resource[idx]; |
184 | end = dev->resource[idx].end; | 183 | |
185 | size = end - start; | 184 | size = res->end - res->start; |
186 | if (size == 0) { | 185 | if (size == 0) |
187 | continue; | 186 | continue; |
188 | } | 187 | |
189 | addr = pcidev_info->pdi_pio_mapped_addr[idx]; | 188 | res->start = pcidev_info->pdi_pio_mapped_addr[idx]; |
190 | addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; | 189 | res->end = addr + size; |
191 | dev->resource[idx].start = addr; | ||
192 | dev->resource[idx].end = addr + size; | ||
193 | 190 | ||
194 | /* | 191 | /* |
195 | * if it's already in the device structure, remove it before | 192 | * if it's already in the device structure, remove it before |
196 | * inserting | 193 | * inserting |
197 | */ | 194 | */ |
198 | if (dev->resource[idx].parent && dev->resource[idx].parent->child) | 195 | if (res->parent && res->parent->child) |
199 | release_resource(&dev->resource[idx]); | 196 | release_resource(res); |
200 | 197 | ||
201 | if (dev->resource[idx].flags & IORESOURCE_IO) | 198 | if (res->flags & IORESOURCE_IO) |
202 | insert_resource(&ioport_resource, &dev->resource[idx]); | 199 | insert_resource(&ioport_resource, res); |
203 | else | 200 | else |
204 | insert_resource(&iomem_resource, &dev->resource[idx]); | 201 | insert_resource(&iomem_resource, res); |
205 | /* | 202 | /* |
206 | * If ROM, set the actual ROM image size, and mark as | 203 | * If ROM, mark as shadowed in PROM. |
207 | * shadowed in PROM. | ||
208 | */ | 204 | */ |
209 | if (idx == PCI_ROM_RESOURCE) { | 205 | if (idx == PCI_ROM_RESOURCE) { |
210 | size_t image_size; | 206 | pci_disable_rom(dev); |
211 | void __iomem *rom; | 207 | res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW | |
212 | 208 | IORESOURCE_PCI_FIXED; | |
213 | rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), | ||
214 | size + 1); | ||
215 | image_size = pci_get_rom_size(dev, rom, size + 1); | ||
216 | dev->resource[PCI_ROM_RESOURCE].end = | ||
217 | dev->resource[PCI_ROM_RESOURCE].start + | ||
218 | image_size - 1; | ||
219 | dev->resource[PCI_ROM_RESOURCE].flags |= | ||
220 | IORESOURCE_ROM_BIOS_COPY; | ||
221 | } | 209 | } |
222 | } | 210 | } |
223 | 211 | ||
224 | sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); | 212 | sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); |
225 | } | 213 | } |
226 | |||
227 | EXPORT_SYMBOL(sn_io_slot_fixup); | 214 | EXPORT_SYMBOL(sn_io_slot_fixup); |
228 | 215 | ||
229 | /* | 216 | /* |
diff --git a/arch/mips/pci/fixup-loongson3.c b/arch/mips/pci/fixup-loongson3.c index d708ae46d325..2b6d5e196f99 100644 --- a/arch/mips/pci/fixup-loongson3.c +++ b/arch/mips/pci/fixup-loongson3.c | |||
@@ -40,20 +40,25 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
40 | 40 | ||
41 | static void pci_fixup_radeon(struct pci_dev *pdev) | 41 | static void pci_fixup_radeon(struct pci_dev *pdev) |
42 | { | 42 | { |
43 | if (pdev->resource[PCI_ROM_RESOURCE].start) | 43 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
44 | |||
45 | if (res->start) | ||
44 | return; | 46 | return; |
45 | 47 | ||
46 | if (!loongson_sysconf.vgabios_addr) | 48 | if (!loongson_sysconf.vgabios_addr) |
47 | return; | 49 | return; |
48 | 50 | ||
49 | pdev->resource[PCI_ROM_RESOURCE].start = | 51 | pci_disable_rom(pdev); |
50 | loongson_sysconf.vgabios_addr; | 52 | if (res->parent) |
51 | pdev->resource[PCI_ROM_RESOURCE].end = | 53 | release_resource(res); |
52 | loongson_sysconf.vgabios_addr + 256*1024 - 1; | 54 | |
53 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_COPY; | 55 | res->start = virt_to_phys((void *) loongson_sysconf.vgabios_addr); |
56 | res->end = res->start + 256*1024 - 1; | ||
57 | res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW | | ||
58 | IORESOURCE_PCI_FIXED; | ||
54 | 59 | ||
55 | dev_info(&pdev->dev, "BAR %d: assigned %pR for Radeon ROM\n", | 60 | dev_info(&pdev->dev, "BAR %d: assigned %pR for Radeon ROM\n", |
56 | PCI_ROM_RESOURCE, &pdev->resource[PCI_ROM_RESOURCE]); | 61 | PCI_ROM_RESOURCE, res); |
57 | } | 62 | } |
58 | 63 | ||
59 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID, | 64 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID, |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index e58565556703..b7de1929714b 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -297,14 +297,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_r | |||
297 | * | 297 | * |
298 | * The standard boot ROM sequence for an x86 machine uses the BIOS | 298 | * The standard boot ROM sequence for an x86 machine uses the BIOS |
299 | * to select an initial video card for boot display. This boot video | 299 | * to select an initial video card for boot display. This boot video |
300 | * card will have it's BIOS copied to C0000 in system RAM. | 300 | * card will have its BIOS copied to 0xC0000 in system RAM. |
301 | * IORESOURCE_ROM_SHADOW is used to associate the boot video | 301 | * IORESOURCE_ROM_SHADOW is used to associate the boot video |
302 | * card with this copy. On laptops this copy has to be used since | 302 | * card with this copy. On laptops this copy has to be used since |
303 | * the main ROM may be compressed or combined with another image. | 303 | * the main ROM may be compressed or combined with another image. |
304 | * See pci_map_rom() for use of this flag. Before marking the device | 304 | * See pci_map_rom() for use of this flag. Before marking the device |
305 | * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set | 305 | * with IORESOURCE_ROM_SHADOW check if a vga_default_device is already set |
306 | * by either arch cde or vga-arbitration, if so only apply the fixup to this | 306 | * by either arch code or vga-arbitration; if so only apply the fixup to this |
307 | * already determined primary video card. | 307 | * already-determined primary video card. |
308 | */ | 308 | */ |
309 | 309 | ||
310 | static void pci_fixup_video(struct pci_dev *pdev) | 310 | static void pci_fixup_video(struct pci_dev *pdev) |
@@ -312,6 +312,7 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
312 | struct pci_dev *bridge; | 312 | struct pci_dev *bridge; |
313 | struct pci_bus *bus; | 313 | struct pci_bus *bus; |
314 | u16 config; | 314 | u16 config; |
315 | struct resource *res; | ||
315 | 316 | ||
316 | /* Is VGA routed to us? */ | 317 | /* Is VGA routed to us? */ |
317 | bus = pdev->bus; | 318 | bus = pdev->bus; |
@@ -336,8 +337,18 @@ static void pci_fixup_video(struct pci_dev *pdev) | |||
336 | if (!vga_default_device() || pdev == vga_default_device()) { | 337 | if (!vga_default_device() || pdev == vga_default_device()) { |
337 | pci_read_config_word(pdev, PCI_COMMAND, &config); | 338 | pci_read_config_word(pdev, PCI_COMMAND, &config); |
338 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | 339 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { |
339 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | 340 | res = &pdev->resource[PCI_ROM_RESOURCE]; |
340 | dev_printk(KERN_DEBUG, &pdev->dev, "Video device with shadowed ROM\n"); | 341 | |
342 | pci_disable_rom(pdev); | ||
343 | if (res->parent) | ||
344 | release_resource(res); | ||
345 | |||
346 | res->start = 0xC0000; | ||
347 | res->end = res->start + 0x20000 - 1; | ||
348 | res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW | | ||
349 | IORESOURCE_PCI_FIXED; | ||
350 | dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n", | ||
351 | res); | ||
341 | } | 352 | } |
342 | } | 353 | } |
343 | } | 354 | } |
@@ -540,3 +551,10 @@ static void twinhead_reserve_killing_zone(struct pci_dev *dev) | |||
540 | } | 551 | } |
541 | } | 552 | } |
542 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone); | 553 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone); |
554 | |||
555 | static void pci_bdwep_bar(struct pci_dev *dev) | ||
556 | { | ||
557 | dev->non_compliant_bars = 1; | ||
558 | } | ||
559 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar); | ||
560 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar); | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index ed39c093aa15..e982010f0ed1 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -1138,33 +1138,36 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) | |||
1138 | /* allocate attribute structure, piggyback attribute name */ | 1138 | /* allocate attribute structure, piggyback attribute name */ |
1139 | int name_len = write_combine ? 13 : 10; | 1139 | int name_len = write_combine ? 13 : 10; |
1140 | struct bin_attribute *res_attr; | 1140 | struct bin_attribute *res_attr; |
1141 | char *res_attr_name; | ||
1141 | int retval; | 1142 | int retval; |
1142 | 1143 | ||
1143 | res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC); | 1144 | res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC); |
1144 | if (res_attr) { | 1145 | if (!res_attr) |
1145 | char *res_attr_name = (char *)(res_attr + 1); | 1146 | return -ENOMEM; |
1146 | 1147 | ||
1147 | sysfs_bin_attr_init(res_attr); | 1148 | res_attr_name = (char *)(res_attr + 1); |
1148 | if (write_combine) { | 1149 | |
1149 | pdev->res_attr_wc[num] = res_attr; | 1150 | sysfs_bin_attr_init(res_attr); |
1150 | sprintf(res_attr_name, "resource%d_wc", num); | 1151 | if (write_combine) { |
1151 | res_attr->mmap = pci_mmap_resource_wc; | 1152 | pdev->res_attr_wc[num] = res_attr; |
1152 | } else { | 1153 | sprintf(res_attr_name, "resource%d_wc", num); |
1153 | pdev->res_attr[num] = res_attr; | 1154 | res_attr->mmap = pci_mmap_resource_wc; |
1154 | sprintf(res_attr_name, "resource%d", num); | 1155 | } else { |
1155 | res_attr->mmap = pci_mmap_resource_uc; | 1156 | pdev->res_attr[num] = res_attr; |
1156 | } | 1157 | sprintf(res_attr_name, "resource%d", num); |
1157 | if (pci_resource_flags(pdev, num) & IORESOURCE_IO) { | 1158 | res_attr->mmap = pci_mmap_resource_uc; |
1158 | res_attr->read = pci_read_resource_io; | 1159 | } |
1159 | res_attr->write = pci_write_resource_io; | 1160 | if (pci_resource_flags(pdev, num) & IORESOURCE_IO) { |
1160 | } | 1161 | res_attr->read = pci_read_resource_io; |
1161 | res_attr->attr.name = res_attr_name; | 1162 | res_attr->write = pci_write_resource_io; |
1162 | res_attr->attr.mode = S_IRUSR | S_IWUSR; | 1163 | } |
1163 | res_attr->size = pci_resource_len(pdev, num); | 1164 | res_attr->attr.name = res_attr_name; |
1164 | res_attr->private = &pdev->resource[num]; | 1165 | res_attr->attr.mode = S_IRUSR | S_IWUSR; |
1165 | retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); | 1166 | res_attr->size = pci_resource_len(pdev, num); |
1166 | } else | 1167 | res_attr->private = &pdev->resource[num]; |
1167 | retval = -ENOMEM; | 1168 | retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); |
1169 | if (retval) | ||
1170 | kfree(res_attr); | ||
1168 | 1171 | ||
1169 | return retval; | 1172 | return retval; |
1170 | } | 1173 | } |
@@ -1360,7 +1363,7 @@ error: | |||
1360 | int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev) | 1363 | int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev) |
1361 | { | 1364 | { |
1362 | int retval; | 1365 | int retval; |
1363 | int rom_size = 0; | 1366 | int rom_size; |
1364 | struct bin_attribute *attr; | 1367 | struct bin_attribute *attr; |
1365 | 1368 | ||
1366 | if (!sysfs_initialized) | 1369 | if (!sysfs_initialized) |
@@ -1377,12 +1380,8 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev) | |||
1377 | if (retval) | 1380 | if (retval) |
1378 | goto err_config_file; | 1381 | goto err_config_file; |
1379 | 1382 | ||
1380 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) | ||
1381 | rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
1382 | else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) | ||
1383 | rom_size = 0x20000; | ||
1384 | |||
1385 | /* If the device has a ROM, try to expose it in sysfs. */ | 1383 | /* If the device has a ROM, try to expose it in sysfs. */ |
1384 | rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
1386 | if (rom_size) { | 1385 | if (rom_size) { |
1387 | attr = kzalloc(sizeof(*attr), GFP_ATOMIC); | 1386 | attr = kzalloc(sizeof(*attr), GFP_ATOMIC); |
1388 | if (!attr) { | 1387 | if (!attr) { |
@@ -1413,7 +1412,7 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev) | |||
1413 | return 0; | 1412 | return 0; |
1414 | 1413 | ||
1415 | err_rom_file: | 1414 | err_rom_file: |
1416 | if (rom_size) { | 1415 | if (pdev->rom_attr) { |
1417 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); | 1416 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); |
1418 | kfree(pdev->rom_attr); | 1417 | kfree(pdev->rom_attr); |
1419 | pdev->rom_attr = NULL; | 1418 | pdev->rom_attr = NULL; |
@@ -1451,8 +1450,6 @@ static void pci_remove_capabilities_sysfs(struct pci_dev *dev) | |||
1451 | */ | 1450 | */ |
1452 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev) | 1451 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev) |
1453 | { | 1452 | { |
1454 | int rom_size = 0; | ||
1455 | |||
1456 | if (!sysfs_initialized) | 1453 | if (!sysfs_initialized) |
1457 | return; | 1454 | return; |
1458 | 1455 | ||
@@ -1465,18 +1462,13 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) | |||
1465 | 1462 | ||
1466 | pci_remove_resource_files(pdev); | 1463 | pci_remove_resource_files(pdev); |
1467 | 1464 | ||
1468 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) | 1465 | if (pdev->rom_attr) { |
1469 | rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
1470 | else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) | ||
1471 | rom_size = 0x20000; | ||
1472 | |||
1473 | if (rom_size && pdev->rom_attr) { | ||
1474 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); | 1466 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); |
1475 | kfree(pdev->rom_attr); | 1467 | kfree(pdev->rom_attr); |
1468 | pdev->rom_attr = NULL; | ||
1476 | } | 1469 | } |
1477 | 1470 | ||
1478 | pci_remove_firmware_label_files(pdev); | 1471 | pci_remove_firmware_label_files(pdev); |
1479 | |||
1480 | } | 1472 | } |
1481 | 1473 | ||
1482 | static int __init pci_sysfs_init(void) | 1474 | static int __init pci_sysfs_init(void) |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c4e1eff8b07c..8004f67c57ec 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -179,6 +179,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
179 | u16 orig_cmd; | 179 | u16 orig_cmd; |
180 | struct pci_bus_region region, inverted_region; | 180 | struct pci_bus_region region, inverted_region; |
181 | 181 | ||
182 | if (dev->non_compliant_bars) | ||
183 | return 0; | ||
184 | |||
182 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 185 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
183 | 186 | ||
184 | /* No printks while decoding is disabled! */ | 187 | /* No printks while decoding is disabled! */ |
@@ -1191,6 +1194,7 @@ static void pci_msi_setup_pci_dev(struct pci_dev *dev) | |||
1191 | int pci_setup_device(struct pci_dev *dev) | 1194 | int pci_setup_device(struct pci_dev *dev) |
1192 | { | 1195 | { |
1193 | u32 class; | 1196 | u32 class; |
1197 | u16 cmd; | ||
1194 | u8 hdr_type; | 1198 | u8 hdr_type; |
1195 | int pos = 0; | 1199 | int pos = 0; |
1196 | struct pci_bus_region region; | 1200 | struct pci_bus_region region; |
@@ -1234,6 +1238,16 @@ int pci_setup_device(struct pci_dev *dev) | |||
1234 | /* device class may be changed after fixup */ | 1238 | /* device class may be changed after fixup */ |
1235 | class = dev->class >> 8; | 1239 | class = dev->class >> 8; |
1236 | 1240 | ||
1241 | if (dev->non_compliant_bars) { | ||
1242 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
1243 | if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | ||
1244 | dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n"); | ||
1245 | cmd &= ~PCI_COMMAND_IO; | ||
1246 | cmd &= ~PCI_COMMAND_MEMORY; | ||
1247 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
1248 | } | ||
1249 | } | ||
1250 | |||
1237 | switch (dev->hdr_type) { /* header type */ | 1251 | switch (dev->hdr_type) { /* header type */ |
1238 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ | 1252 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ |
1239 | if (class == PCI_CLASS_BRIDGE_PCI) | 1253 | if (class == PCI_CLASS_BRIDGE_PCI) |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index d35c7fcde3af..8982026637d5 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -7,7 +7,6 @@ static void pci_free_resources(struct pci_dev *dev) | |||
7 | { | 7 | { |
8 | int i; | 8 | int i; |
9 | 9 | ||
10 | pci_cleanup_rom(dev); | ||
11 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 10 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
12 | struct resource *res = dev->resource + i; | 11 | struct resource *res = dev->resource + i; |
13 | if (res->parent) | 12 | if (res->parent) |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 9eaca39ef38d..06663d391b39 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -24,13 +24,17 @@ | |||
24 | */ | 24 | */ |
25 | int pci_enable_rom(struct pci_dev *pdev) | 25 | int pci_enable_rom(struct pci_dev *pdev) |
26 | { | 26 | { |
27 | struct resource *res = pdev->resource + PCI_ROM_RESOURCE; | 27 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
28 | struct pci_bus_region region; | 28 | struct pci_bus_region region; |
29 | u32 rom_addr; | 29 | u32 rom_addr; |
30 | 30 | ||
31 | if (!res->flags) | 31 | if (!res->flags) |
32 | return -1; | 32 | return -1; |
33 | 33 | ||
34 | /* Nothing to enable if we're using a shadow copy in RAM */ | ||
35 | if (res->flags & IORESOURCE_ROM_SHADOW) | ||
36 | return 0; | ||
37 | |||
34 | pcibios_resource_to_bus(pdev->bus, ®ion, res); | 38 | pcibios_resource_to_bus(pdev->bus, ®ion, res); |
35 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); | 39 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); |
36 | rom_addr &= ~PCI_ROM_ADDRESS_MASK; | 40 | rom_addr &= ~PCI_ROM_ADDRESS_MASK; |
@@ -49,7 +53,12 @@ EXPORT_SYMBOL_GPL(pci_enable_rom); | |||
49 | */ | 53 | */ |
50 | void pci_disable_rom(struct pci_dev *pdev) | 54 | void pci_disable_rom(struct pci_dev *pdev) |
51 | { | 55 | { |
56 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | ||
52 | u32 rom_addr; | 57 | u32 rom_addr; |
58 | |||
59 | if (res->flags & IORESOURCE_ROM_SHADOW) | ||
60 | return; | ||
61 | |||
53 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); | 62 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); |
54 | rom_addr &= ~PCI_ROM_ADDRESS_ENABLE; | 63 | rom_addr &= ~PCI_ROM_ADDRESS_ENABLE; |
55 | pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); | 64 | pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); |
@@ -119,43 +128,23 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
119 | loff_t start; | 128 | loff_t start; |
120 | void __iomem *rom; | 129 | void __iomem *rom; |
121 | 130 | ||
122 | /* | 131 | /* assign the ROM an address if it doesn't have one */ |
123 | * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy | 132 | if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE)) |
124 | * memory map if the VGA enable bit of the Bridge Control register is | 133 | return NULL; |
125 | * set for embedded VGA. | 134 | |
126 | */ | 135 | start = pci_resource_start(pdev, PCI_ROM_RESOURCE); |
127 | if (res->flags & IORESOURCE_ROM_SHADOW) { | 136 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
128 | /* primary video rom always starts here */ | 137 | if (*size == 0) |
129 | start = (loff_t)0xC0000; | 138 | return NULL; |
130 | *size = 0x20000; /* cover C000:0 through E000:0 */ | 139 | |
131 | } else { | 140 | /* Enable ROM space decodes */ |
132 | if (res->flags & | 141 | if (pci_enable_rom(pdev)) |
133 | (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) { | 142 | return NULL; |
134 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
135 | return (void __iomem *)(unsigned long) | ||
136 | pci_resource_start(pdev, PCI_ROM_RESOURCE); | ||
137 | } else { | ||
138 | /* assign the ROM an address if it doesn't have one */ | ||
139 | if (res->parent == NULL && | ||
140 | pci_assign_resource(pdev, PCI_ROM_RESOURCE)) | ||
141 | return NULL; | ||
142 | start = pci_resource_start(pdev, PCI_ROM_RESOURCE); | ||
143 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
144 | if (*size == 0) | ||
145 | return NULL; | ||
146 | |||
147 | /* Enable ROM space decodes */ | ||
148 | if (pci_enable_rom(pdev)) | ||
149 | return NULL; | ||
150 | } | ||
151 | } | ||
152 | 143 | ||
153 | rom = ioremap(start, *size); | 144 | rom = ioremap(start, *size); |
154 | if (!rom) { | 145 | if (!rom) { |
155 | /* restore enable if ioremap fails */ | 146 | /* restore enable if ioremap fails */ |
156 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | | 147 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) |
157 | IORESOURCE_ROM_SHADOW | | ||
158 | IORESOURCE_ROM_COPY))) | ||
159 | pci_disable_rom(pdev); | 148 | pci_disable_rom(pdev); |
160 | return NULL; | 149 | return NULL; |
161 | } | 150 | } |
@@ -181,37 +170,15 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) | |||
181 | { | 170 | { |
182 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | 171 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
183 | 172 | ||
184 | if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) | ||
185 | return; | ||
186 | |||
187 | iounmap(rom); | 173 | iounmap(rom); |
188 | 174 | ||
189 | /* Disable again before continuing, leave enabled if pci=rom */ | 175 | /* Disable again before continuing */ |
190 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW))) | 176 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) |
191 | pci_disable_rom(pdev); | 177 | pci_disable_rom(pdev); |
192 | } | 178 | } |
193 | EXPORT_SYMBOL(pci_unmap_rom); | 179 | EXPORT_SYMBOL(pci_unmap_rom); |
194 | 180 | ||
195 | /** | 181 | /** |
196 | * pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy | ||
197 | * @pdev: pointer to pci device struct | ||
198 | * | ||
199 | * Free the copied ROM if we allocated one. | ||
200 | */ | ||
201 | void pci_cleanup_rom(struct pci_dev *pdev) | ||
202 | { | ||
203 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | ||
204 | |||
205 | if (res->flags & IORESOURCE_ROM_COPY) { | ||
206 | kfree((void *)(unsigned long)res->start); | ||
207 | res->flags |= IORESOURCE_UNSET; | ||
208 | res->flags &= ~IORESOURCE_ROM_COPY; | ||
209 | res->start = 0; | ||
210 | res->end = 0; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * pci_platform_rom - provides a pointer to any ROM image provided by the | 182 | * pci_platform_rom - provides a pointer to any ROM image provided by the |
216 | * platform | 183 | * platform |
217 | * @pdev: pointer to pci device struct | 184 | * @pdev: pointer to pci device struct |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 604011e047d6..66c4d8f42233 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -276,6 +276,9 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
276 | resource_size_t align, size; | 276 | resource_size_t align, size; |
277 | int ret; | 277 | int ret; |
278 | 278 | ||
279 | if (res->flags & IORESOURCE_PCI_FIXED) | ||
280 | return 0; | ||
281 | |||
279 | res->flags |= IORESOURCE_UNSET; | 282 | res->flags |= IORESOURCE_UNSET; |
280 | align = pci_resource_alignment(dev, res); | 283 | align = pci_resource_alignment(dev, res); |
281 | if (!align) { | 284 | if (!align) { |
@@ -321,6 +324,9 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
321 | resource_size_t new_size; | 324 | resource_size_t new_size; |
322 | int ret; | 325 | int ret; |
323 | 326 | ||
327 | if (res->flags & IORESOURCE_PCI_FIXED) | ||
328 | return 0; | ||
329 | |||
324 | flags = res->flags; | 330 | flags = res->flags; |
325 | res->flags |= IORESOURCE_UNSET; | 331 | res->flags |= IORESOURCE_UNSET; |
326 | if (!res->parent) { | 332 | if (!res->parent) { |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 24bea087e7af..29a6deb9f054 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -98,9 +98,7 @@ struct resource { | |||
98 | 98 | ||
99 | /* PCI ROM control bits (IORESOURCE_BITS) */ | 99 | /* PCI ROM control bits (IORESOURCE_BITS) */ |
100 | #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ | 100 | #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ |
101 | #define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ | 101 | #define IORESOURCE_ROM_SHADOW (1<<1) /* Use RAM image, not ROM BAR */ |
102 | #define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */ | ||
103 | #define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */ | ||
104 | 102 | ||
105 | /* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */ | 103 | /* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */ |
106 | #define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */ | 104 | #define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index bd757f3c721c..15f466e52d0d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -353,6 +353,7 @@ struct pci_dev { | |||
353 | unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */ | 353 | unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */ |
354 | unsigned int irq_managed:1; | 354 | unsigned int irq_managed:1; |
355 | unsigned int has_secondary_link:1; | 355 | unsigned int has_secondary_link:1; |
356 | unsigned int non_compliant_bars:1; /* broken BARs; ignore them */ | ||
356 | pci_dev_flags_t dev_flags; | 357 | pci_dev_flags_t dev_flags; |
357 | atomic_t enable_cnt; /* pci_enable_device has been called */ | 358 | atomic_t enable_cnt; /* pci_enable_device has been called */ |
358 | 359 | ||