setup-res.c (275d38585c742acdd6b8ab20f2588552f04c5d31) setup-res.c (2bbc6942273b5b3097bd265d82227bdd84b351b2)
1/*
2 * drivers/pci/setup-res.c
3 *
4 * Extruded from code written by
5 * Dave Rusling (david.rusling@reo.mts.dec.com)
6 * David Mosberger (davidm@cs.arizona.edu)
7 * David Miller (davem@redhat.com)
8 *

--- 114 unchanged lines hidden (view full) ---

123
124 /* Prefetchable MMIO Base/Limit */
125 pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
126 pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
127 pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
128}
129#endif /* CONFIG_PCI_QUIRKS */
130
1/*
2 * drivers/pci/setup-res.c
3 *
4 * Extruded from code written by
5 * Dave Rusling (david.rusling@reo.mts.dec.com)
6 * David Mosberger (davidm@cs.arizona.edu)
7 * David Miller (davem@redhat.com)
8 *

--- 114 unchanged lines hidden (view full) ---

123
124 /* Prefetchable MMIO Base/Limit */
125 pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
126 pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
127 pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
128}
129#endif /* CONFIG_PCI_QUIRKS */
130
131
132
131static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
133static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
132 int resno)
134 int resno, resource_size_t size, resource_size_t align)
133{
134 struct resource *res = dev->resource + resno;
135{
136 struct resource *res = dev->resource + resno;
135 resource_size_t size, min, align;
137 resource_size_t min;
136 int ret;
137
138 int ret;
139
138 size = resource_size(res);
139 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
140 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
140 align = pci_resource_alignment(dev, res);
141
142 /* First, try exact prefetching match.. */
143 ret = pci_bus_alloc_resource(bus, res, size, align, min,
144 IORESOURCE_PREFETCH,
145 pcibios_align_resource, dev);
146
147 if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) {
148 /*
149 * That failed.
150 *
151 * But a prefetching area can handle a non-prefetching
152 * window (it will just not perform as well).
153 */
154 ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
155 pcibios_align_resource, dev);
156 }
141
142 /* First, try exact prefetching match.. */
143 ret = pci_bus_alloc_resource(bus, res, size, align, min,
144 IORESOURCE_PREFETCH,
145 pcibios_align_resource, dev);
146
147 if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) {
148 /*
149 * That failed.
150 *
151 * But a prefetching area can handle a non-prefetching
152 * window (it will just not perform as well).
153 */
154 ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
155 pcibios_align_resource, dev);
156 }
157 return ret;
158}
157
159
158 if (ret < 0 && dev->fw_addr[resno]) {
159 struct resource *root, *conflict;
160 resource_size_t start, end;
160static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
161 int resno, resource_size_t size)
162{
163 struct resource *root, *conflict;
164 resource_size_t start, end;
165 int ret = 0;
161
166
162 /*
163 * If we failed to assign anything, let's try the address
164 * where firmware left it. That at least has a chance of
165 * working, which is better than just leaving it disabled.
166 */
167 if (res->flags & IORESOURCE_IO)
168 root = &ioport_resource;
169 else
170 root = &iomem_resource;
167
171
168 if (res->flags & IORESOURCE_IO)
169 root = &ioport_resource;
172 start = res->start;
173 end = res->end;
174 res->start = dev->fw_addr[resno];
175 res->end = res->start + size - 1;
176 dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n",
177 resno, res);
178 conflict = request_resource_conflict(root, res);
179 if (conflict) {
180 dev_info(&dev->dev,
181 "BAR %d: %pR conflicts with %s %pR\n", resno,
182 res, conflict->name, conflict);
183 res->start = start;
184 res->end = end;
185 ret = 1;
186 }
187 return ret;
188}
189
190static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resource_size_t min_align)
191{
192 struct resource *res = dev->resource + resno;
193 struct pci_bus *bus;
194 int ret;
195 char *type;
196
197 bus = dev->bus;
198 while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
199 if (!bus->parent || !bus->self->transparent)
200 break;
201 bus = bus->parent;
202 }
203
204 if (ret) {
205 if (res->flags & IORESOURCE_MEM)
206 if (res->flags & IORESOURCE_PREFETCH)
207 type = "mem pref";
208 else
209 type = "mem";
210 else if (res->flags & IORESOURCE_IO)
211 type = "io";
170 else
212 else
171 root = &iomem_resource;
213 type = "unknown";
214 dev_info(&dev->dev,
215 "BAR %d: can't assign %s (size %#llx)\n",
216 resno, type, (unsigned long long) resource_size(res));
217 }
172
218
173 start = res->start;
174 end = res->end;
175 res->start = dev->fw_addr[resno];
176 res->end = res->start + size - 1;
177 dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n",
178 resno, res);
179 conflict = request_resource_conflict(root, res);
180 if (conflict) {
181 dev_info(&dev->dev,
182 "BAR %d: %pR conflicts with %s %pR\n", resno,
183 res, conflict->name, conflict);
184 res->start = start;
185 res->end = end;
186 } else
187 ret = 0;
219 return ret;
220}
221
222int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
223 resource_size_t min_align)
224{
225 struct resource *res = dev->resource + resno;
226 resource_size_t new_size;
227 int ret;
228
229 if (!res->parent) {
230 dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resouce %pR "
231 "\n", resno, res);
232 return -EINVAL;
188 }
189
233 }
234
235 new_size = resource_size(res) + addsize + min_align;
236 ret = _pci_assign_resource(dev, resno, new_size, min_align);
190 if (!ret) {
191 res->flags &= ~IORESOURCE_STARTALIGN;
192 dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
193 if (resno < PCI_BRIDGE_RESOURCES)
194 pci_update_resource(dev, resno);
195 }
237 if (!ret) {
238 res->flags &= ~IORESOURCE_STARTALIGN;
239 dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
240 if (resno < PCI_BRIDGE_RESOURCES)
241 pci_update_resource(dev, resno);
242 }
196
197 return ret;
198}
199
200int pci_assign_resource(struct pci_dev *dev, int resno)
201{
202 struct resource *res = dev->resource + resno;
243 return ret;
244}
245
246int pci_assign_resource(struct pci_dev *dev, int resno)
247{
248 struct resource *res = dev->resource + resno;
203 resource_size_t align;
249 resource_size_t align, size;
204 struct pci_bus *bus;
205 int ret;
250 struct pci_bus *bus;
251 int ret;
206 char *type;
207
208 align = pci_resource_alignment(dev, res);
209 if (!align) {
210 dev_info(&dev->dev, "BAR %d: can't assign %pR "
211 "(bogus alignment)\n", resno, res);
212 return -EINVAL;
213 }
214
215 bus = dev->bus;
252
253 align = pci_resource_alignment(dev, res);
254 if (!align) {
255 dev_info(&dev->dev, "BAR %d: can't assign %pR "
256 "(bogus alignment)\n", resno, res);
257 return -EINVAL;
258 }
259
260 bus = dev->bus;
216 while ((ret = __pci_assign_resource(bus, dev, resno))) {
217 if (bus->parent && bus->self->transparent)
218 bus = bus->parent;
219 else
220 bus = NULL;
221 if (bus)
222 continue;
223 break;
224 }
261 size = resource_size(res);
262 ret = _pci_assign_resource(dev, resno, size, align);
225
263
226 if (ret) {
227 if (res->flags & IORESOURCE_MEM)
228 if (res->flags & IORESOURCE_PREFETCH)
229 type = "mem pref";
230 else
231 type = "mem";
232 else if (res->flags & IORESOURCE_IO)
233 type = "io";
234 else
235 type = "unknown";
236 dev_info(&dev->dev,
237 "BAR %d: can't assign %s (size %#llx)\n",
238 resno, type, (unsigned long long) resource_size(res));
239 }
264 /*
265 * If we failed to assign anything, let's try the address
266 * where firmware left it. That at least has a chance of
267 * working, which is better than just leaving it disabled.
268 */
269 if (ret < 0 && dev->fw_addr[resno])
270 ret = pci_revert_fw_address(res, dev, resno, size);
240
271
272 if (!ret) {
273 res->flags &= ~IORESOURCE_STARTALIGN;
274 dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
275 if (resno < PCI_BRIDGE_RESOURCES)
276 pci_update_resource(dev, resno);
277 }
241 return ret;
242}
243
278 return ret;
279}
280
281
244/* Sort resources by alignment */
245void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
246{
247 int i;
248
249 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
250 struct resource *r;
251 struct resource_list *list, *tmp;

--- 78 unchanged lines hidden ---
282/* Sort resources by alignment */
283void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
284{
285 int i;
286
287 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
288 struct resource *r;
289 struct resource_list *list, *tmp;

--- 78 unchanged lines hidden ---