Index: sys/compat/linuxkpi/common/include/linux/dma-mapping.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/dma-mapping.h +++ sys/compat/linuxkpi/common/include/linux/dma-mapping.h @@ -103,6 +103,7 @@ void linux_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents __unused, enum dma_data_direction dir __unused, unsigned long attrs __unused); +void linuxkpi_dma_sync(struct device *, dma_addr_t, size_t, bus_dmasync_op_t); static inline int dma_supported(struct device *dev, u64 dma_mask) @@ -208,6 +209,21 @@ dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { + bus_dmasync_op_t op; + + switch (direction) { + case DMA_BIDIRECTIONAL: + op = BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE | \ + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE; + case DMA_TO_DEVICE: + op = BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE; + case DMA_FROM_DEVICE: + op = BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE; + default: + return; + } + + linuxkpi_dma_sync(dev, dma_handle, size, op); } static inline void @@ -221,6 +237,21 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { + bus_dmasync_op_t op; + + switch (direction) { + case DMA_BIDIRECTIONAL: + op = BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE | \ + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE; + case DMA_TO_DEVICE: + op = BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE; + case DMA_FROM_DEVICE: + op = BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE; + default: + return; + } + + linuxkpi_dma_sync(dev, dma_handle, size, op); } static inline void Index: sys/compat/linuxkpi/common/src/linux_pci.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_pci.c +++ sys/compat/linuxkpi/common/src/linux_pci.c @@ -935,6 +935,29 @@ return (mem); } +void +linuxkpi_dma_sync(struct device *dev, dma_addr_t dma_addr, size_t size, + bus_dmasync_op_t op) +{ + struct linux_dma_priv *priv; + struct linux_dma_obj *obj; + + priv = dev->dma_priv; + + if (pctrie_is_empty(&priv->ptree)) + return; + + DMA_PRIV_LOCK(priv); + obj = LINUX_DMA_PCTRIE_LOOKUP(&priv->ptree, dma_addr); + if (obj == NULL) { + DMA_PRIV_UNLOCK(priv); + return; + } + + bus_dmamap_sync(obj->dmat, obj->dmamap, op); + DMA_PRIV_UNLOCK(priv); +} + int linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction dir __unused, unsigned long attrs __unused)