The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0a575891211eff545bab1e4de5e2b7adf4a4c1da

commit 0a575891211eff545bab1e4de5e2b7adf4a4c1da
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2026-01-21 13:57:55 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2026-01-25 12:35:22 +0000

    LinuxKPI: implement dmam_free_coherent()
    
    dmam_free_coherent() is used by an updated mt76 driver at v6.19-rc6.
    We need to surgically find the devres information and destroy it before
    calling dma_free_coherent.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
    Reviewed by:    emaste
    Differential Revision: https://reviews.freebsd.org/D54810
---
 .../linuxkpi/common/include/linux/dma-mapping.h    |  9 ++++++
 sys/compat/linuxkpi/common/src/linux_pci.c         | 36 ++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h 
b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
index 2d8e1196d3d3..76efbfd51074 100644
--- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
+++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
@@ -96,6 +96,8 @@ void *linux_dma_alloc_coherent(struct device *dev, size_t 
size,
     dma_addr_t *dma_handle, gfp_t flag);
 void *linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size,
     dma_addr_t *dma_handle, gfp_t flag);
+void linuxkpi_dmam_free_coherent(struct device *dev, size_t size,
+    void *addr, dma_addr_t dma_handle);
 dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t 
len);        /* backward compat */
 dma_addr_t lkpi_dma_map_phys(struct device *, vm_paddr_t, size_t,
     enum dma_data_direction, unsigned long);
@@ -181,6 +183,13 @@ dma_free_coherent(struct device *dev, size_t size, void 
*cpu_addr,
        kmem_free(cpu_addr, size);
 }
 
+static inline void
+dmam_free_coherent(struct device *dev, size_t size, void *addr,
+    dma_addr_t dma_handle)
+{
+       linuxkpi_dmam_free_coherent(dev, size, addr, dma_handle);
+}
+
 static inline dma_addr_t
 dma_map_page_attrs(struct device *dev, struct page *page, size_t offset,
     size_t size, enum dma_data_direction direction, unsigned long attrs)
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c 
b/sys/compat/linuxkpi/common/src/linux_pci.c
index df5255d8a6ca..9e4fad45433a 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -1796,6 +1796,42 @@ lkpi_dmam_free_coherent(struct device *dev, void *p)
        dma_free_coherent(dev, dr->size, dr->mem, *dr->handle);
 }
 
+static int
+lkpi_dmam_coherent_match(struct device *dev, void *dr, void *mp)
+{
+       struct lkpi_devres_dmam_coherent *a, *b;
+
+       a = dr;
+       b = mp;
+
+       if (a->mem != b->mem)
+               return (0);
+       if (a->size != b->size || a->handle != b->handle)
+               dev_WARN(dev, "for mem %p: size %zu != %zu || handle %#jx != 
%#jx\n",
+                   a->mem, a->size, b->size,
+                   (uintmax_t)a->handle, (uintmax_t)b->handle);
+       return (1);
+}
+
+void
+linuxkpi_dmam_free_coherent(struct device *dev, size_t size,
+    void *addr, dma_addr_t dma_handle)
+{
+       struct lkpi_devres_dmam_coherent match = {
+               .size           = size,
+               .handle         = &dma_handle,
+               .mem            = addr
+       };
+       int error;
+
+       error = devres_destroy(dev, lkpi_dmam_free_coherent,
+           lkpi_dmam_coherent_match, &match);
+       if (error != 0)
+               dev_WARN(dev, "devres_destroy returned %d, size %zu addr %p "
+                   "dma_handle %#jx\n", error, size, addr, 
(uintmax_t)dma_handle);
+       dma_free_coherent(dev, size, addr, dma_handle);
+}
+
 void *
 linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t 
*dma_handle,
     gfp_t flag)

Reply via email to