diff options
Diffstat (limited to 'drivers/pci/setup-res.c')
-rw-r--r-- | drivers/pci/setup-res.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 9526e341988b..4bc589ee78d0 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -25,21 +25,18 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include "pci.h" | 26 | #include "pci.h" |
27 | 27 | ||
28 | 28 | static void pci_std_update_resource(struct pci_dev *dev, int resno) | |
29 | void pci_update_resource(struct pci_dev *dev, int resno) | ||
30 | { | 29 | { |
31 | struct pci_bus_region region; | 30 | struct pci_bus_region region; |
32 | bool disable; | 31 | bool disable; |
33 | u16 cmd; | 32 | u16 cmd; |
34 | u32 new, check, mask; | 33 | u32 new, check, mask; |
35 | int reg; | 34 | int reg; |
36 | enum pci_bar_type type; | ||
37 | struct resource *res = dev->resource + resno; | 35 | struct resource *res = dev->resource + resno; |
38 | 36 | ||
39 | if (dev->is_virtfn) { | 37 | /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */ |
40 | dev_warn(&dev->dev, "can't update VF BAR%d\n", resno); | 38 | if (dev->is_virtfn) |
41 | return; | 39 | return; |
42 | } | ||
43 | 40 | ||
44 | /* | 41 | /* |
45 | * Ignore resources for unimplemented BARs and unused resource slots | 42 | * Ignore resources for unimplemented BARs and unused resource slots |
@@ -60,21 +57,34 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
60 | return; | 57 | return; |
61 | 58 | ||
62 | pcibios_resource_to_bus(dev->bus, ®ion, res); | 59 | pcibios_resource_to_bus(dev->bus, ®ion, res); |
60 | new = region.start; | ||
63 | 61 | ||
64 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 62 | if (res->flags & IORESOURCE_IO) { |
65 | if (res->flags & IORESOURCE_IO) | ||
66 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; | 63 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; |
67 | else | 64 | new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK; |
65 | } else if (resno == PCI_ROM_RESOURCE) { | ||
66 | mask = (u32)PCI_ROM_ADDRESS_MASK; | ||
67 | } else { | ||
68 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; | 68 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; |
69 | new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; | ||
70 | } | ||
69 | 71 | ||
70 | reg = pci_resource_bar(dev, resno, &type); | 72 | if (resno < PCI_ROM_RESOURCE) { |
71 | if (!reg) | 73 | reg = PCI_BASE_ADDRESS_0 + 4 * resno; |
72 | return; | 74 | } else if (resno == PCI_ROM_RESOURCE) { |
73 | if (type != pci_bar_unknown) { | 75 | |
76 | /* | ||
77 | * Apparently some Matrox devices have ROM BARs that read | ||
78 | * as zero when disabled, so don't update ROM BARs unless | ||
79 | * they're enabled. See https://lkml.org/lkml/2005/8/30/138. | ||
80 | */ | ||
74 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) | 81 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) |
75 | return; | 82 | return; |
83 | |||
84 | reg = dev->rom_base_reg; | ||
76 | new |= PCI_ROM_ADDRESS_ENABLE; | 85 | new |= PCI_ROM_ADDRESS_ENABLE; |
77 | } | 86 | } else |
87 | return; | ||
78 | 88 | ||
79 | /* | 89 | /* |
80 | * We can't update a 64-bit BAR atomically, so when possible, | 90 | * We can't update a 64-bit BAR atomically, so when possible, |
@@ -110,6 +120,16 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
110 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 120 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
111 | } | 121 | } |
112 | 122 | ||
123 | void pci_update_resource(struct pci_dev *dev, int resno) | ||
124 | { | ||
125 | if (resno <= PCI_ROM_RESOURCE) | ||
126 | pci_std_update_resource(dev, resno); | ||
127 | #ifdef CONFIG_PCI_IOV | ||
128 | else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) | ||
129 | pci_iov_update_resource(dev, resno); | ||
130 | #endif | ||
131 | } | ||
132 | |||
113 | int pci_claim_resource(struct pci_dev *dev, int resource) | 133 | int pci_claim_resource(struct pci_dev *dev, int resource) |
114 | { | 134 | { |
115 | struct resource *res = &dev->resource[resource]; | 135 | struct resource *res = &dev->resource[resource]; |