diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h --- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h +++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h @@ -97,12 +97,12 @@ void *linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag); dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len); -void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t size); +void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction); int linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, - int nents, enum dma_data_direction dir __unused, + int nents, enum dma_data_direction direction, unsigned long attrs __unused); void linux_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, - int nents __unused, enum dma_data_direction dir __unused, + int nents __unused, enum dma_data_direction direction, unsigned long attrs __unused); void linuxkpi_dma_sync(struct device *, dma_addr_t, size_t, bus_dmasync_op_t); @@ -173,15 +173,17 @@ dma_addr_t dma_addr) { - linux_dma_unmap(dev, dma_addr, size); + pr_debug("%s:%d: TODO DMA_NONE?\n", __func__, __LINE__); + linux_dma_unmap(dev, dma_addr, size, DMA_NONE); kmem_free(cpu_addr, size); } 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 dir, unsigned long attrs) + size_t size, enum dma_data_direction direction, unsigned long attrs __unused) { + pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction); return (linux_dma_map_phys(dev, page_to_phys(page) + offset, size)); } @@ -197,6 +199,7 @@ unsigned long offset, size_t size, enum dma_data_direction direction) { + pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction); return (linux_dma_map_phys(dev, page_to_phys(page) + offset, size)); } @@ -205,7 +208,7 @@ enum dma_data_direction direction) { - linux_dma_unmap(dev, dma_address, size); + linux_dma_unmap(dev, dma_address, size, direction); } static inline void @@ -267,24 +270,28 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { + pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction); } static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { + pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction); } static inline void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, - unsigned long offset, size_t size, int direction) + unsigned long offset, size_t size, enum dma_data_direction direction) { + pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction); } static inline void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, - unsigned long offset, size_t size, int direction) + unsigned long offset, size_t size, enum dma_data_direction direction) { + pr_debug("%s:%d: TODO dir %d\n", __func__, __LINE__, direction); } #define DMA_MAPPING_ERROR (~(dma_addr_t)0) @@ -323,7 +330,7 @@ { dma_sync_single_for_cpu(dev, dma, size, direction); - linux_dma_unmap(dev, dma, size); + linux_dma_unmap(dev, dma, size, direction); } static inline size_t diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -1482,7 +1482,8 @@ #if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) void -linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len) +linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len, + enum dma_data_direction direction) { struct linux_dma_priv *priv; struct linux_dma_obj *obj; @@ -1499,6 +1500,22 @@ return; } LINUX_DMA_PCTRIE_REMOVE(&priv->ptree, dma_addr); + + switch (direction) { + case DMA_BIDIRECTIONAL: + bus_dmamap_sync(obj->dmat, obj->dmamap, BUS_DMASYNC_POSTREAD); + bus_dmamap_sync(obj->dmat, obj->dmamap, BUS_DMASYNC_PREREAD); + break; + case DMA_TO_DEVICE: + bus_dmamap_sync(obj->dmat, obj->dmamap, BUS_DMASYNC_POSTWRITE); + break; + case DMA_FROM_DEVICE: + bus_dmamap_sync(obj->dmat, obj->dmamap, BUS_DMASYNC_POSTREAD); + break; + default: + break; + } + bus_dmamap_unload(obj->dmat, obj->dmamap); bus_dmamap_destroy(obj->dmat, obj->dmamap); DMA_PRIV_UNLOCK(priv); @@ -1507,7 +1524,8 @@ } #else void -linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len) +linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len, + enum dma_data_direction direction) { } #endif