diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-05-19 20:32:18 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-05-23 14:40:49 -0400 |
commit | 67d29b5c6c40e91b124695e9250c2fd24915e24a (patch) | |
tree | 38def8abdc769db7adc071f445afb00435849af9 | |
parent | d3689df04445c568c8b3dfcd8db4b562e1b18cfb (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.c | 58 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 35 |
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 | ||