Skip to content

Commit bd43348

Browse files
committed
Merge branch 'pci/endpoint'
- Add pci_epc_function_is_valid() to avoid repeating common validation checks (Damien Le Moal) - Skip attempts to allocate from endpoint controller memory window if the requested size is larger than the window (Damien Le Moal) - Add and document pci_epc_mem_map() and pci_epc_mem_unmap() to handle controller-specific size and alignment constraints, and add test cases to the endpoint test driver (Damien Le Moal) - Implement dwc pci_epc_ops.align_addr() so pci_epc_mem_map() can observe DWC-specific alignment requirements (Damien Le Moal) - Synchronously cancel command handler work in endpoint test before cleaning up DMA and BARs (Damien Le Moal) - Respect endpoint page size in dw_pcie_ep_align_addr() (Niklas Cassel) - Use dw_pcie_ep_align_addr() in dw_pcie_ep_raise_msi_irq() and dw_pcie_ep_raise_msix_irq() instead of open coding the equivalent (Niklas Cassel) - Remove superfluous 'return' from pci_epf_test_clean_dma_chan() (Wang Jiang) - Avoid NULL dereference if Modem Host Interface Endpoint lacks 'mmio' DT property (Zhongqiu Han) - Release PCI domain ID of Endpoint controller parent (not controller itself) and before unregistering the controller, to avoid use-after-free (Zijun Hu) - Clear secondary (not primary) EPC in pci_epc_remove_epf() when removing the secondary controller associated with an NTB (Zijun Hu) - Fix pci_epc_map map_size kerneldoc (Rick Wertenbroek) * pci/endpoint: PCI: endpoint: Fix pci_epc_map map_size kerneldoc string PCI: endpoint: Clear secondary (not primary) EPC in pci_epc_remove_epf() PCI: endpoint: Fix PCI domain ID release in pci_epc_destroy() PCI: endpoint: epf-mhi: Avoid NULL dereference if DT lacks 'mmio' PCI: endpoint: Remove surplus return statement from pci_epf_test_clean_dma_chan() PCI: dwc: ep: Use align addr function for dw_pcie_ep_raise_{msi,msix}_irq() PCI: endpoint: test: Synchronously cancel command handler work PCI: dwc: endpoint: Implement the pci_epc_ops::align_addr() operation PCI: endpoint: test: Use pci_epc_mem_map/unmap() PCI: endpoint: Update documentation PCI: endpoint: Introduce pci_epc_mem_map()/unmap() PCI: endpoint: Improve pci_epc_mem_alloc_addr() PCI: endpoint: Introduce pci_epc_function_is_valid()
2 parents 0683141 + 28b6acd commit bd43348

File tree

7 files changed

+438
-250
lines changed

7 files changed

+438
-250
lines changed

Documentation/PCI/endpoint/pci-endpoint.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,35 @@ by the PCI endpoint function driver.
117117
The PCI endpoint function driver should use pci_epc_mem_free_addr() to
118118
free the memory space allocated using pci_epc_mem_alloc_addr().
119119

120+
* pci_epc_map_addr()
121+
122+
A PCI endpoint function driver should use pci_epc_map_addr() to map to a RC
123+
PCI address the CPU address of local memory obtained with
124+
pci_epc_mem_alloc_addr().
125+
126+
* pci_epc_unmap_addr()
127+
128+
A PCI endpoint function driver should use pci_epc_unmap_addr() to unmap the
129+
CPU address of local memory mapped to a RC address with pci_epc_map_addr().
130+
131+
* pci_epc_mem_map()
132+
133+
A PCI endpoint controller may impose constraints on the RC PCI addresses that
134+
can be mapped. The function pci_epc_mem_map() allows endpoint function
135+
drivers to allocate and map controller memory while handling such
136+
constraints. This function will determine the size of the memory that must be
137+
allocated with pci_epc_mem_alloc_addr() for successfully mapping a RC PCI
138+
address range. This function will also indicate the size of the PCI address
139+
range that was actually mapped, which can be less than the requested size, as
140+
well as the offset into the allocated memory to use for accessing the mapped
141+
RC PCI address range.
142+
143+
* pci_epc_mem_unmap()
144+
145+
A PCI endpoint function driver can use pci_epc_mem_unmap() to unmap and free
146+
controller memory that was allocated and mapped using pci_epc_mem_map().
147+
148+
120149
Other EPC APIs
121150
~~~~~~~~~~~~~~
122151

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,20 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
268268
return -EINVAL;
269269
}
270270

271+
static u64 dw_pcie_ep_align_addr(struct pci_epc *epc, u64 pci_addr,
272+
size_t *pci_size, size_t *offset)
273+
{
274+
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
275+
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
276+
u64 mask = pci->region_align - 1;
277+
size_t ofst = pci_addr & mask;
278+
279+
*pci_size = ALIGN(ofst + *pci_size, epc->mem->window.page_size);
280+
*offset = ofst;
281+
282+
return pci_addr & ~mask;
283+
}
284+
271285
static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
272286
phys_addr_t addr)
273287
{
@@ -444,6 +458,7 @@ static const struct pci_epc_ops epc_ops = {
444458
.write_header = dw_pcie_ep_write_header,
445459
.set_bar = dw_pcie_ep_set_bar,
446460
.clear_bar = dw_pcie_ep_clear_bar,
461+
.align_addr = dw_pcie_ep_align_addr,
447462
.map_addr = dw_pcie_ep_map_addr,
448463
.unmap_addr = dw_pcie_ep_unmap_addr,
449464
.set_msi = dw_pcie_ep_set_msi,
@@ -488,7 +503,8 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
488503
u32 msg_addr_lower, msg_addr_upper, reg;
489504
struct dw_pcie_ep_func *ep_func;
490505
struct pci_epc *epc = ep->epc;
491-
unsigned int aligned_offset;
506+
size_t map_size = sizeof(u32);
507+
size_t offset;
492508
u16 msg_ctrl, msg_data;
493509
bool has_upper;
494510
u64 msg_addr;
@@ -516,14 +532,13 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
516532
}
517533
msg_addr = ((u64)msg_addr_upper) << 32 | msg_addr_lower;
518534

519-
aligned_offset = msg_addr & (epc->mem->window.page_size - 1);
520-
msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size);
535+
msg_addr = dw_pcie_ep_align_addr(epc, msg_addr, &map_size, &offset);
521536
ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
522-
epc->mem->window.page_size);
537+
map_size);
523538
if (ret)
524539
return ret;
525540

526-
writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset);
541+
writel(msg_data | (interrupt_num - 1), ep->msi_mem + offset);
527542

528543
dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
529544

@@ -574,8 +589,9 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
574589
struct pci_epf_msix_tbl *msix_tbl;
575590
struct dw_pcie_ep_func *ep_func;
576591
struct pci_epc *epc = ep->epc;
592+
size_t map_size = sizeof(u32);
593+
size_t offset;
577594
u32 reg, msg_data, vec_ctrl;
578-
unsigned int aligned_offset;
579595
u32 tbl_offset;
580596
u64 msg_addr;
581597
int ret;
@@ -600,14 +616,13 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
600616
return -EPERM;
601617
}
602618

603-
aligned_offset = msg_addr & (epc->mem->window.page_size - 1);
604-
msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size);
619+
msg_addr = dw_pcie_ep_align_addr(epc, msg_addr, &map_size, &offset);
605620
ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
606-
epc->mem->window.page_size);
621+
map_size);
607622
if (ret)
608623
return ret;
609624

610-
writel(msg_data, ep->msi_mem + aligned_offset);
625+
writel(msg_data, ep->msi_mem + offset);
611626

612627
dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
613628

drivers/pci/endpoint/functions/pci-epf-mhi.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,12 +867,18 @@ static int pci_epf_mhi_bind(struct pci_epf *epf)
867867
{
868868
struct pci_epf_mhi *epf_mhi = epf_get_drvdata(epf);
869869
struct pci_epc *epc = epf->epc;
870+
struct device *dev = &epf->dev;
870871
struct platform_device *pdev = to_platform_device(epc->dev.parent);
871872
struct resource *res;
872873
int ret;
873874

874875
/* Get MMIO base address from Endpoint controller */
875876
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mmio");
877+
if (!res) {
878+
dev_err(dev, "Failed to get \"mmio\" resource\n");
879+
return -ENODEV;
880+
}
881+
876882
epf_mhi->mmio_phys = res->start;
877883
epf_mhi->mmio_size = resource_size(res);
878884

0 commit comments

Comments
 (0)