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 | dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, atu_index); | 165 | dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, atu_index); |
| 166 | clear_bit(atu_index, ep->ib_window_map); | 166 | clear_bit(atu_index, ep->ib_window_map); |
| 167 | ep_func->bar_to_atu[bar] = 0; | 167 | ep_func->bar_to_atu[bar] = 0; |
| 168 | return; | ||
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | /* Tear down all Address Match Mode mappings, if any. */ | 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 | * We can only dynamically change a BAR if the new BAR size and | 520 | * We can only dynamically change a BAR if the new BAR size and |
| 520 | * BAR flags do not differ from the existing configuration. | 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 | if (ep_func->epf_bar[bar]->barno != bar || | 529 | if (ep_func->epf_bar[bar]->barno != bar || |
| 523 | ep_func->epf_bar[bar]->size != size || | 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 | * When dynamically changing a BAR, tear down any existing | 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) | 541 | dw_pcie_ep_clear_ib_maps(ep, func_no, bar); |
| 532 | dw_pcie_ep_clear_ib_maps(ep, func_no, bar); | ||
| 533 | 542 | ||
| 534 | /* | 543 | /* |
| 535 | * When dynamically changing a BAR, skip writing the BAR reg, as | 544 | * When dynamically changing a BAR, skip writing the BAR reg, as |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | config PCI_EPF_TEST | 6 | config PCI_EPF_TEST |
| 7 | tristate "PCI Endpoint Test driver" | 7 | tristate "PCI Endpoint Test driver" |
| 8 | depends on PCI_ENDPOINT | 8 | depends on PCI_ENDPOINT |
| 9 | select CONFIGFS_FS | ||
| 9 | select CRC32 | 10 | select CRC32 |
| 10 | help | 11 | help |
| 11 | Enable this configuration option to enable the test driver | 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 | switch (iores_type) { | 225 | switch (iores_type) { |
| 226 | case IORESOURCE_IO: | 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 | case IORESOURCE_MEM: | 232 | case IORESOURCE_MEM: |
| 230 | mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); | 233 | mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); |
| 231 | mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); | 234 | mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); |
| 232 | 235 | ||
| 233 | if (!(type & IORESOURCE_PREFETCH) || | 236 | if (mmio && !(mmio->flags & IORESOURCE_MEM)) |
| 234 | !(mmio_pref->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 | return mmio; | 242 | return mmio; |
| 236 | 243 | ||
| 237 | if ((type & IORESOURCE_MEM_64) || | 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 | struct resource *res = pci_resource_n(dev, resno); | 1224 | struct resource *res = pci_resource_n(dev, resno); |
| 1218 | bool optional = pci_resource_is_optional(dev, resno); | 1225 | bool optional = pci_resource_is_optional(dev, resno); |
| 1219 | resource_size_t r_size = resource_size(res); | 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 | if (!realloc_head) | 1229 | if (!realloc_head) |
| 1223 | return false; | 1230 | return false; |
| 1224 | 1231 | ||
| 1225 | if (!optional) { | 1232 | /* |
| 1226 | /* | 1233 | * Only bridges have optional sizes in realloc_head at this |
| 1227 | * Only bridges have optional sizes in realloc_head at this | 1234 | * point. As res_to_dev_res() walks the entire realloc_head |
| 1228 | * point. As res_to_dev_res() walks the entire realloc_head | 1235 | * list, skip calling it when known unnecessary. |
| 1229 | * list, skip calling it when known unnecessary. | 1236 | */ |
| 1230 | */ | 1237 | if (pci_resource_is_bridge_win(resno)) { |
| 1231 | if (!pci_resource_is_bridge_win(resno)) | ||
| 1232 | return false; | ||
| 1233 | |||
| 1234 | dev_res = res_to_dev_res(realloc_head, res); | 1238 | dev_res = res_to_dev_res(realloc_head, res); |
| 1235 | if (dev_res) { | 1239 | if (dev_res) { |
| 1236 | *children_add_size += dev_res->add_size; | 1240 | *children_add_size += dev_res->add_size; |
| 1237 | *add_align = max(*add_align, dev_res->min_align); | 1241 | *add_align = max(*add_align, dev_res->min_align); |
| 1238 | } | 1242 | } |
| 1243 | } | ||
| 1239 | 1244 | ||
| 1245 | if (!optional) | ||
| 1240 | return false; | 1246 | return false; |
| 1241 | } | ||
| 1242 | 1247 | ||
| 1243 | /* Put SRIOV requested res to the optional list */ | 1248 | /* |
| 1244 | pci_dev_res_add_to_list(realloc_head, dev, res, 0, align); | 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 | *children_add_size += r_size; | 1255 | *children_add_size += r_size; |
| 1246 | *add_align = max(align, *add_align); | 1256 | *add_align = max(align, *add_align); |
| 1247 | 1257 | ||