aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-05-19 20:32:18 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-05-23 14:40:49 -0400
commit67d29b5c6c40e91b124695e9250c2fd24915e24a (patch)
tree38def8abdc769db7adc071f445afb00435849af9
parentd3689df04445c568c8b3dfcd8db4b562e1b18cfb (diff)
PCI: Add resource allocation comments
Add comments in the code to match the allocation strategy of 7c671426dfc3 ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources"). No functional change. Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/setup-bus.c58
-rw-r--r--drivers/pci/setup-res.c35
2 files changed, 62 insertions, 31 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 12ab50ffdfea..455ee0364956 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1164,17 +1164,16 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
1164 additional_io_size = pci_hotplug_io_size; 1164 additional_io_size = pci_hotplug_io_size;
1165 additional_mem_size = pci_hotplug_mem_size; 1165 additional_mem_size = pci_hotplug_mem_size;
1166 } 1166 }
1167 /* 1167 /* Fall through */
1168 * Follow thru
1169 */
1170 default: 1168 default:
1171 pbus_size_io(bus, realloc_head ? 0 : additional_io_size, 1169 pbus_size_io(bus, realloc_head ? 0 : additional_io_size,
1172 additional_io_size, realloc_head); 1170 additional_io_size, realloc_head);
1173 /* If the bridge supports prefetchable range, size it 1171
1174 separately. If it doesn't, or its prefetchable window 1172 /*
1175 has already been allocated by arch code, try 1173 * If there's a 64-bit prefetchable MMIO window, compute
1176 non-prefetchable range for both types of PCI memory 1174 * the size required to put all 64-bit prefetchable
1177 resources. */ 1175 * resources in it.
1176 */
1178 b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES]; 1177 b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES];
1179 mask = IORESOURCE_MEM; 1178 mask = IORESOURCE_MEM;
1180 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; 1179 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
@@ -1184,29 +1183,58 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
1184 prefmask, prefmask, 1183 prefmask, prefmask,
1185 realloc_head ? 0 : additional_mem_size, 1184 realloc_head ? 0 : additional_mem_size,
1186 additional_mem_size, realloc_head); 1185 additional_mem_size, realloc_head);
1186
1187 /*
1188 * If successful, all non-prefetchable resources
1189 * and any 32-bit prefetchable resources will go in
1190 * the non-prefetchable window.
1191 */
1187 if (ret == 0) { 1192 if (ret == 0) {
1188 /*
1189 * Success, with pref mmio64,
1190 * next will size non-pref or
1191 * non-mmio64 */
1192 mask = prefmask; 1193 mask = prefmask;
1193 type2 = prefmask & ~IORESOURCE_MEM_64; 1194 type2 = prefmask & ~IORESOURCE_MEM_64;
1194 type3 = prefmask & ~IORESOURCE_PREFETCH; 1195 type3 = prefmask & ~IORESOURCE_PREFETCH;
1195 } 1196 }
1196 } 1197 }
1198
1199 /*
1200 * If there is no 64-bit prefetchable window, compute the
1201 * size required to put all prefetchable resources in the
1202 * 32-bit prefetchable window (if there is one).
1203 */
1197 if (!type2) { 1204 if (!type2) {
1198 prefmask &= ~IORESOURCE_MEM_64; 1205 prefmask &= ~IORESOURCE_MEM_64;
1199 ret = pbus_size_mem(bus, prefmask, prefmask, 1206 ret = pbus_size_mem(bus, prefmask, prefmask,
1200 prefmask, prefmask, 1207 prefmask, prefmask,
1201 realloc_head ? 0 : additional_mem_size, 1208 realloc_head ? 0 : additional_mem_size,
1202 additional_mem_size, realloc_head); 1209 additional_mem_size, realloc_head);
1203 if (ret == 0) { 1210
1204 /* Success, next will size non-prefetch. */ 1211 /*
1212 * If successful, only non-prefetchable resources
1213 * will go in the non-prefetchable window.
1214 */
1215 if (ret == 0)
1205 mask = prefmask; 1216 mask = prefmask;
1206 } else 1217 else
1207 additional_mem_size += additional_mem_size; 1218 additional_mem_size += additional_mem_size;
1219
1208 type2 = type3 = IORESOURCE_MEM; 1220 type2 = type3 = IORESOURCE_MEM;
1209 } 1221 }
1222
1223 /*
1224 * Compute the size required to put everything else in the
1225 * non-prefetchable window. This includes:
1226 *
1227 * - all non-prefetchable resources
1228 * - 32-bit prefetchable resources if there's a 64-bit
1229 * prefetchable window or no prefetchable window at all
1230 * - 64-bit prefetchable resources if there's no
1231 * prefetchable window at all
1232 *
1233 * Note that the strategy in __pci_assign_resource() must
1234 * match that used here. Specifically, we cannot put a
1235 * 32-bit prefetchable resource in a 64-bit prefetchable
1236 * window.
1237 */
1210 pbus_size_mem(bus, mask, IORESOURCE_MEM, type2, type3, 1238 pbus_size_mem(bus, mask, IORESOURCE_MEM, type2, type3,
1211 realloc_head ? 0 : additional_mem_size, 1239 realloc_head ? 0 : additional_mem_size,
1212 additional_mem_size, realloc_head); 1240 additional_mem_size, realloc_head);
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 3bdac9dc4a88..3da2542eb4df 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -209,20 +209,25 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
209 209
210 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; 210 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
211 211
212 /* First, try exact prefetching match.. */ 212 /*
213 * First, try exact prefetching match. Even if a 64-bit
214 * prefetchable bridge window is below 4GB, we can't put a 32-bit
215 * prefetchable resource in it because pbus_size_mem() assumes a
216 * 64-bit window will contain no 32-bit resources. If we assign
217 * things differently than they were sized, not everything will fit.
218 */
213 ret = pci_bus_alloc_resource(bus, res, size, align, min, 219 ret = pci_bus_alloc_resource(bus, res, size, align, min,
214 IORESOURCE_PREFETCH | IORESOURCE_MEM_64, 220 IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
215 pcibios_align_resource, dev); 221 pcibios_align_resource, dev);
216 if (ret == 0) 222 if (ret == 0)
217 return 0; 223 return 0;
218 224
225 /*
226 * If the prefetchable window is only 32 bits wide, we can put
227 * 64-bit prefetchable resources in it.
228 */
219 if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) == 229 if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
220 (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) { 230 (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
221 /*
222 * That failed.
223 *
224 * Try 32bit pref
225 */
226 ret = pci_bus_alloc_resource(bus, res, size, align, min, 231 ret = pci_bus_alloc_resource(bus, res, size, align, min,
227 IORESOURCE_PREFETCH, 232 IORESOURCE_PREFETCH,
228 pcibios_align_resource, dev); 233 pcibios_align_resource, dev);
@@ -230,18 +235,16 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
230 return 0; 235 return 0;
231 } 236 }
232 237
233 if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) { 238 /*
234 /* 239 * If we didn't find a better match, we can put any memory resource
235 * That failed. 240 * in a non-prefetchable window. If this resource is 32 bits and
236 * 241 * non-prefetchable, the first call already tried the only possibility
237 * But a prefetching area can handle a non-prefetching 242 * so we don't need to try again.
238 * window (it will just not perform as well). 243 */
239 * 244 if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
240 * Also can put 64bit under 32bit range. (below 4g).
241 */
242 ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, 245 ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
243 pcibios_align_resource, dev); 246 pcibios_align_resource, dev);
244 } 247
245 return ret; 248 return ret;
246} 249}
247 250