diff options
Diffstat (limited to 'drivers/pci/setup-res.c')
-rw-r--r-- | drivers/pci/setup-res.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 12403516776a..b711fb7181e2 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -135,23 +135,16 @@ void pci_disable_bridge_window(struct pci_dev *dev) | |||
135 | } | 135 | } |
136 | #endif /* CONFIG_PCI_QUIRKS */ | 136 | #endif /* CONFIG_PCI_QUIRKS */ |
137 | 137 | ||
138 | int pci_assign_resource(struct pci_dev *dev, int resno) | 138 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
139 | int resno) | ||
139 | { | 140 | { |
140 | struct pci_bus *bus = dev->bus; | ||
141 | struct resource *res = dev->resource + resno; | 141 | struct resource *res = dev->resource + resno; |
142 | resource_size_t size, min, align; | 142 | resource_size_t size, min, align; |
143 | int ret; | 143 | int ret; |
144 | 144 | ||
145 | size = resource_size(res); | 145 | size = resource_size(res); |
146 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; | 146 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; |
147 | |||
148 | align = resource_alignment(res); | 147 | align = resource_alignment(res); |
149 | if (!align) { | ||
150 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " | ||
151 | "alignment) %pR flags %#lx\n", | ||
152 | resno, res, res->flags); | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | 148 | ||
156 | /* First, try exact prefetching match.. */ | 149 | /* First, try exact prefetching match.. */ |
157 | ret = pci_bus_alloc_resource(bus, res, size, align, min, | 150 | ret = pci_bus_alloc_resource(bus, res, size, align, min, |
@@ -169,10 +162,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
169 | pcibios_align_resource, dev); | 162 | pcibios_align_resource, dev); |
170 | } | 163 | } |
171 | 164 | ||
172 | if (ret) { | 165 | if (!ret) { |
173 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | ||
174 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | ||
175 | } else { | ||
176 | res->flags &= ~IORESOURCE_STARTALIGN; | 166 | res->flags &= ~IORESOURCE_STARTALIGN; |
177 | if (resno < PCI_BRIDGE_RESOURCES) | 167 | if (resno < PCI_BRIDGE_RESOURCES) |
178 | pci_update_resource(dev, resno); | 168 | pci_update_resource(dev, resno); |
@@ -181,6 +171,39 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
181 | return ret; | 171 | return ret; |
182 | } | 172 | } |
183 | 173 | ||
174 | int pci_assign_resource(struct pci_dev *dev, int resno) | ||
175 | { | ||
176 | struct resource *res = dev->resource + resno; | ||
177 | resource_size_t align; | ||
178 | struct pci_bus *bus; | ||
179 | int ret; | ||
180 | |||
181 | align = resource_alignment(res); | ||
182 | if (!align) { | ||
183 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " | ||
184 | "alignment) %pR flags %#lx\n", | ||
185 | resno, res, res->flags); | ||
186 | return -EINVAL; | ||
187 | } | ||
188 | |||
189 | bus = dev->bus; | ||
190 | while ((ret = __pci_assign_resource(bus, dev, resno))) { | ||
191 | if (bus->parent && bus->self->transparent) | ||
192 | bus = bus->parent; | ||
193 | else | ||
194 | bus = NULL; | ||
195 | if (bus) | ||
196 | continue; | ||
197 | break; | ||
198 | } | ||
199 | |||
200 | if (ret) | ||
201 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | ||
202 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | ||
203 | |||
204 | return ret; | ||
205 | } | ||
206 | |||
184 | #if 0 | 207 | #if 0 |
185 | int pci_assign_resource_fixed(struct pci_dev *dev, int resno) | 208 | int pci_assign_resource_fixed(struct pci_dev *dev, int resno) |
186 | { | 209 | { |