From af13c69522abc992de9fe652d229de9e71251c0c Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 28 May 2021 11:11:28 +0000 Subject: [PATCH] LinuxKPI: add dmam_pool_create() support dmam_pool_create() is a "managed" version of dma_pool_create() which will cleanup everything left when the device goes away using the devres framework. For that add an internal cleanup function to be called from devres release. This is used by at least one wireless driver. Sponsored by: The FreeBSD Foundation Reviewed by: hselasky Differential Revision: https://reviews.freebsd.org/D30520 (cherry picked from commit 2afeed13b58653578c6ce5154afa6fb59f6b47f0) --- .../linuxkpi/common/include/linux/dmapool.h | 20 +++++++++++++++++++ sys/compat/linuxkpi/common/src/linux_pci.c | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/dmapool.h b/sys/compat/linuxkpi/common/include/linux/dmapool.h index 980d5d74884..60353ede6a8 100644 --- a/sys/compat/linuxkpi/common/include/linux/dmapool.h +++ b/sys/compat/linuxkpi/common/include/linux/dmapool.h @@ -41,6 +41,7 @@ struct dma_pool; struct dma_pool *linux_dma_pool_create(char *name, struct device *dev, size_t size, size_t align, size_t boundary); void linux_dma_pool_destroy(struct dma_pool *pool); +void lkpi_dmam_pool_destroy(struct device *, void *); void *linux_dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, dma_addr_t *handle); void linux_dma_pool_free(struct dma_pool *pool, void *vaddr, @@ -54,6 +55,25 @@ dma_pool_create(char *name, struct device *dev, size_t size, return (linux_dma_pool_create(name, dev, size, align, boundary)); } +static inline struct dma_pool * +dmam_pool_create(/* const */ char *name, struct device *dev, size_t size, + size_t align, size_t boundary) +{ + struct dma_pool **pp; + + pp = devres_alloc(lkpi_dmam_pool_destroy, sizeof(*pp), GFP_KERNEL); + if (pp == NULL) + return (NULL); + *pp = linux_dma_pool_create(name, dev, size, align, boundary); + if (*pp == NULL) { + devres_free(pp); + return (NULL); + } + + devres_add(dev, pp); + return (*pp); +} + static inline void dma_pool_destroy(struct dma_pool *pool) { diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index 075df3c2adf..7aa159600fa 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -997,6 +997,16 @@ linux_dma_pool_destroy(struct dma_pool *pool) kfree(pool); } +void +lkpi_dmam_pool_destroy(struct device *dev, void *p) +{ + struct dma_pool *pool; + + pool = *(struct dma_pool **)p; + LINUX_DMA_PCTRIE_RECLAIM(&pool->pool_ptree); + linux_dma_pool_destroy(pool); +} + void * linux_dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, dma_addr_t *handle)