Pull pci fixes from Bjorn Helgaas: - Fix bridge window selection bug that prevented resource assignment (Kai-Heng Feng) - Fix bridge window sizing, which failed to assign resources for windows containing only optional resources (ROMs, SR-IOV BARs, etc) (Ilpo Järvinen) - Select CONFIGFS_FS when PCI_EPF_TEST is enabled to avoid a link error (Arnd Bergmann) - Fix recently merged Endpoint inbound submapping feature (Koichiro Den) * tag 'pci-v7.0-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: PCI: dwc: ep: Always clear IB maps on BAR update PCI: dwc: ep: Return after clearing BAR-match inbound mapping PCI: endpoint: pci-epf-test: Select configfs PCI: Account fully optional bridge windows correctly PCI: Validate window resource type in pbus_select_window_for_type()
Unified · Split
| @@ -165,6 +165,7 @@ static void dw_pcie_ep_clear_ib_maps(struct dw_pcie_ep *ep, u8 func_no, enum pci · 164 unmodified lines | ||
| 165 | 165 | dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, atu_index); |
| 166 | 166 | clear_bit(atu_index, ep->ib_window_map); |
| 167 | 167 | ep_func->bar_to_atu[bar] = 0; |
| 168 | + return; | |
| 168 | 169 | } |
| 169 | 170 | |
| 170 | 171 | /* Tear down all Address Match Mode mappings, if any. */ |
| @@ -518,6 +519,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, · 347 unmodified lines | ||
| 518 | 519 | /* |
| 519 | 520 | * We can only dynamically change a BAR if the new BAR size and |
| 520 | 521 | * BAR flags do not differ from the existing configuration. |
| 522 | + * | |
| 523 | + * Note: this safety check only works when the caller uses | |
| 524 | + * a new struct pci_epf_bar in the second set_bar() call. | |
| 525 | + * If the same instance is updated in place and passed in, | |
| 526 | + * we cannot reliably detect invalid barno/size/flags | |
| 527 | + * changes here. | |
| 521 | 528 | */ |
| 522 | 529 | if (ep_func->epf_bar[bar]->barno != bar || |
| 523 | 530 | ep_func->epf_bar[bar]->size != size || |
| @@ -526,10 +533,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, · 2 unmodified lines | ||
| 526 | 533 | |
| 527 | 534 | /* |
| 528 | 535 | * When dynamically changing a BAR, tear down any existing |
| 529 | − * mappings before re-programming. | |
| 536 | + * mappings before re-programming. This is redundant when | |
| 537 | + * both the old and new mappings are BAR Match Mode, but | |
| 538 | + * required to handle in-place updates and match-mode | |
| 539 | + * changes reliably. | |
| 530 | 540 | */ |
| 531 | − if (ep_func->epf_bar[bar]->num_submap || epf_bar->num_submap) | |
| 532 | − dw_pcie_ep_clear_ib_maps(ep, func_no, bar); | |
| 541 | + dw_pcie_ep_clear_ib_maps(ep, func_no, bar); | |
| 533 | 542 | |
| 534 | 543 | /* |
| 535 | 544 | * When dynamically changing a BAR, skip writing the BAR reg, as |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | config PCI_EPF_TEST |
| 7 | 7 | tristate "PCI Endpoint Test driver" |
| 8 | 8 | depends on PCI_ENDPOINT |
| 9 | + select CONFIGFS_FS | |
| 9 | 10 | select CRC32 |
| 10 | 11 | help |
| 11 | 12 | Enable this configuration option to enable the test driver |
| @@ -224,14 +224,21 @@ static struct resource *pbus_select_window_for_type(struct pci_bus *bus, · 223 unmodified lines | ||
| 224 | 224 | |
| 225 | 225 | switch (iores_type) { |
| 226 | 226 | case IORESOURCE_IO: |
| 227 | − return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); | |
| 227 | + win = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); | |
| 228 | + if (win && (win->flags & IORESOURCE_IO)) | |
| 229 | + return win; | |
| 230 | + return NULL; | |
| 228 | 231 | |
| 229 | 232 | case IORESOURCE_MEM: |
| 230 | 233 | mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); |
| 231 | 234 | mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); |
| 232 | 235 | |
| 233 | − if (!(type & IORESOURCE_PREFETCH) || | |
| 234 | − !(mmio_pref->flags & IORESOURCE_MEM)) | |
| 236 | + if (mmio && !(mmio->flags & IORESOURCE_MEM)) | |
| 237 | + mmio = NULL; | |
| 238 | + if (mmio_pref && !(mmio_pref->flags & IORESOURCE_MEM)) | |
| 239 | + mmio_pref = NULL; | |
| 240 | + | |
| 241 | + if (!(type & IORESOURCE_PREFETCH) || !mmio_pref) | |
| 235 | 242 | return mmio; |
| 236 | 243 | |
| 237 | 244 | if ((type & IORESOURCE_MEM_64) || |
| @@ -1217,31 +1224,34 @@ static bool pbus_size_mem_optional(struct pci_dev *dev, int resno, · 979 unmodified lines | ||
| 1217 | 1224 | struct resource *res = pci_resource_n(dev, resno); |
| 1218 | 1225 | bool optional = pci_resource_is_optional(dev, resno); |
| 1219 | 1226 | resource_size_t r_size = resource_size(res); |
| 1220 | − struct pci_dev_resource *dev_res; | |
| 1227 | + struct pci_dev_resource *dev_res = NULL; | |
| 1221 | 1228 | |
| 1222 | 1229 | if (!realloc_head) |
| 1223 | 1230 | return false; |
| 1224 | 1231 | |
| 1225 | − if (!optional) { | |
| 1226 | − /* | |
| 1227 | − * Only bridges have optional sizes in realloc_head at this | |
| 1228 | − * point. As res_to_dev_res() walks the entire realloc_head | |
| 1229 | − * list, skip calling it when known unnecessary. | |
| 1230 | − */ | |
| 1231 | − if (!pci_resource_is_bridge_win(resno)) | |
| 1232 | − return false; | |
| 1233 | − | |
| 1232 | + /* | |
| 1233 | + * Only bridges have optional sizes in realloc_head at this | |
| 1234 | + * point. As res_to_dev_res() walks the entire realloc_head | |
| 1235 | + * list, skip calling it when known unnecessary. | |
| 1236 | + */ | |
| 1237 | + if (pci_resource_is_bridge_win(resno)) { | |
| 1234 | 1238 | dev_res = res_to_dev_res(realloc_head, res); |
| 1235 | 1239 | if (dev_res) { |
| 1236 | 1240 | *children_add_size += dev_res->add_size; |
| 1237 | 1241 | *add_align = max(*add_align, dev_res->min_align); |
| 1238 | 1242 | } |
| 1243 | + } | |
| 1239 | 1244 | |
| 1245 | + if (!optional) | |
| 1240 | 1246 | return false; |
| 1241 | − } | |
| 1242 | 1247 | |
| 1243 | − /* Put SRIOV requested res to the optional list */ | |
| 1244 | − pci_dev_res_add_to_list(realloc_head, dev, res, 0, align); | |
| 1248 | + /* | |
| 1249 | + * Put requested res to the optional list if not there yet (SR-IOV, | |
| 1250 | + * disabled ROM). Bridge windows with an optional part are already | |
| 1251 | + * on the list. | |
| 1252 | + */ | |
| 1253 | + if (!dev_res) | |
| 1254 | + pci_dev_res_add_to_list(realloc_head, dev, res, 0, align); | |
| 1245 | 1255 | *children_add_size += r_size; |
| 1246 | 1256 | *add_align = max(align, *add_align); |
| 1247 | 1257 | |