diff options
-rw-r--r-- | drivers/pci/setup-res.c | 107 |
1 files changed, 54 insertions, 53 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 1a0e60e265ea..81b88bda7930 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -145,33 +145,6 @@ void pci_disable_bridge_window(struct pci_dev *dev) | |||
145 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); | 145 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); |
146 | } | 146 | } |
147 | 147 | ||
148 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | ||
149 | int resno, resource_size_t size, resource_size_t align) | ||
150 | { | ||
151 | struct resource *res = dev->resource + resno; | ||
152 | resource_size_t min; | ||
153 | int ret; | ||
154 | |||
155 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; | ||
156 | |||
157 | /* First, try exact prefetching match.. */ | ||
158 | ret = pci_bus_alloc_resource(bus, res, size, align, min, | ||
159 | IORESOURCE_PREFETCH, | ||
160 | pcibios_align_resource, dev); | ||
161 | |||
162 | if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) { | ||
163 | /* | ||
164 | * That failed. | ||
165 | * | ||
166 | * But a prefetching area can handle a non-prefetching | ||
167 | * window (it will just not perform as well). | ||
168 | */ | ||
169 | ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, | ||
170 | pcibios_align_resource, dev); | ||
171 | } | ||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | /* | 148 | /* |
176 | * Generic function that returns a value indicating that the device's | 149 | * Generic function that returns a value indicating that the device's |
177 | * original BIOS BAR address was not saved and so is not available for | 150 | * original BIOS BAR address was not saved and so is not available for |
@@ -224,7 +197,35 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | |||
224 | return ret; | 197 | return ret; |
225 | } | 198 | } |
226 | 199 | ||
227 | static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resource_size_t min_align) | 200 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
201 | int resno, resource_size_t size, resource_size_t align) | ||
202 | { | ||
203 | struct resource *res = dev->resource + resno; | ||
204 | resource_size_t min; | ||
205 | int ret; | ||
206 | |||
207 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; | ||
208 | |||
209 | /* First, try exact prefetching match.. */ | ||
210 | ret = pci_bus_alloc_resource(bus, res, size, align, min, | ||
211 | IORESOURCE_PREFETCH, | ||
212 | pcibios_align_resource, dev); | ||
213 | |||
214 | if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) { | ||
215 | /* | ||
216 | * That failed. | ||
217 | * | ||
218 | * But a prefetching area can handle a non-prefetching | ||
219 | * window (it will just not perform as well). | ||
220 | */ | ||
221 | ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, | ||
222 | pcibios_align_resource, dev); | ||
223 | } | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | static int _pci_assign_resource(struct pci_dev *dev, int resno, | ||
228 | resource_size_t size, resource_size_t min_align) | ||
228 | { | 229 | { |
229 | struct resource *res = dev->resource + resno; | 230 | struct resource *res = dev->resource + resno; |
230 | struct pci_bus *bus; | 231 | struct pci_bus *bus; |
@@ -256,31 +257,6 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resour | |||
256 | return ret; | 257 | return ret; |
257 | } | 258 | } |
258 | 259 | ||
259 | int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize, | ||
260 | resource_size_t min_align) | ||
261 | { | ||
262 | struct resource *res = dev->resource + resno; | ||
263 | resource_size_t new_size; | ||
264 | int ret; | ||
265 | |||
266 | if (!res->parent) { | ||
267 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " | ||
268 | "\n", resno, res); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | |||
272 | /* already aligned with min_align */ | ||
273 | new_size = resource_size(res) + addsize; | ||
274 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | ||
275 | if (!ret) { | ||
276 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
277 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | ||
278 | if (resno < PCI_BRIDGE_RESOURCES) | ||
279 | pci_update_resource(dev, resno); | ||
280 | } | ||
281 | return ret; | ||
282 | } | ||
283 | |||
284 | int pci_assign_resource(struct pci_dev *dev, int resno) | 260 | int pci_assign_resource(struct pci_dev *dev, int resno) |
285 | { | 261 | { |
286 | struct resource *res = dev->resource + resno; | 262 | struct resource *res = dev->resource + resno; |
@@ -316,6 +292,31 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
316 | return ret; | 292 | return ret; |
317 | } | 293 | } |
318 | 294 | ||
295 | int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize, | ||
296 | resource_size_t min_align) | ||
297 | { | ||
298 | struct resource *res = dev->resource + resno; | ||
299 | resource_size_t new_size; | ||
300 | int ret; | ||
301 | |||
302 | if (!res->parent) { | ||
303 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " | ||
304 | "\n", resno, res); | ||
305 | return -EINVAL; | ||
306 | } | ||
307 | |||
308 | /* already aligned with min_align */ | ||
309 | new_size = resource_size(res) + addsize; | ||
310 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | ||
311 | if (!ret) { | ||
312 | res->flags &= ~IORESOURCE_STARTALIGN; | ||
313 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | ||
314 | if (resno < PCI_BRIDGE_RESOURCES) | ||
315 | pci_update_resource(dev, resno); | ||
316 | } | ||
317 | return ret; | ||
318 | } | ||
319 | |||
319 | int pci_enable_resources(struct pci_dev *dev, int mask) | 320 | int pci_enable_resources(struct pci_dev *dev, int mask) |
320 | { | 321 | { |
321 | u16 cmd, old_cmd; | 322 | u16 cmd, old_cmd; |