On 4/17/2020 9:55 AM, Christoph Hellwig wrote:
dma_direct_unmap_sg(dev, sglist, nelems, direction, attrs);
}
+static dma_addr_t dma_iommu_map_resource(struct device *dev,
+ phys_addr_t phys_addr, size_t size,
+ enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_controller *phb = pci_bus_to_host(pdev->bus);
+
+ if (dma_iommu_map_bypass(dev, attrs)) {
+ if (phb->controller_ops.dma_map_resource &&
+ phb->controller_ops.dma_map_resource(pdev, phys_addr, size,
+ dir))
+ return DMA_MAPPING_ERROR;
+ return dma_direct_map_resource(dev, phys_addr, size,
+ dir, attrs);
+ }
+ return DMA_MAPPING_ERROR;
Just a nitpick, but to the return errors early would be a much more
logical flow. Also if the callback just decides if the mapping is
possible in bypass mode it should have that in the name:
struct pci_controller_ops *ops = &phb->controller_ops;
if (!dma_iommu_map_bypass(dev, attrs) ||
!ops->dma_can_direct_map_resource ||
!ops->dma_can_direct_map_resource(pdev, phys_addr, size, dir)
return DMA_MAPPING_ERROR;
return dma_direct_map_resource(dev, phys_addr, size, dir, attrs);
maybe call it dma_direct_map_resource/dma_direct_unmap_resource for
symmetry ?
do you mean (small logic change):
if (!dma_iommu_map_bypass(dev, attrs) ||
!ops->dma_direct_map_resource ||
ops->dma_direct_map_resource(pdev, phys_addr, size, dir))
return DMA_MAPPING_ERROR;
return dma_direct_map_resource(dev, phys_addr, size, dir, attrs);
+ if (dma_iommu_map_bypass(dev, attrs)) {
+ if (phb->controller_ops.dma_unmap_resource)
+ phb->controller_ops.dma_unmap_resource(pdev, dma_handle,
+ size, dir);
+ }
This can do a little early return as well, coupled with a WARN_ON_ONCE
as we should never end up in the unmap path for a setup where the map didn't
work.
how about:
struct pci_controller_ops *ops = &phb->controller_ops;
if (dma_iommu_map_bypass(dev, attrs) &&
ops->dma_direct_unmap_resource)
ops->dma_direct_unmap_resource(pdev, dma_handle, size,
dir);