#include <linux/dma-mapping.h>
 #include <asm/dma-mapping.h>
 
-static dma_addr_t pci32_map_single(struct device *dev, void *ptr,
+static dma_addr_t pci32_map_single(struct device *dev, phys_addr_t ptr,
                                   size_t size, int direction)
 {
        WARN_ON(size == 0);
        flush_write_buffers();
-       return virt_to_phys(ptr);
+       return ptr;
 }
 
 static int pci32_dma_map_sg(struct device *dev, struct scatterlist *sglist,
 
        return 0;
 }
 
-static dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
+static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr,
        size_t size, int direction)
 {
        dma_addr_t dma_handle = bad_dma_address;
+       void *vaddr = phys_to_virt(paddr);
        unsigned long uaddr;
        unsigned int npages;
        struct iommu_table *tbl = find_iommu_table(dev);
 
        }
 
        if (dma_ops->map_simple) {
-               *dma_handle = dma_ops->map_simple(dev, memory,
+               *dma_handle = dma_ops->map_simple(dev, virt_to_phys(memory),
                                              size,
                                              PCI_DMA_BIDIRECTIONAL);
                if (*dma_handle != bad_dma_address)
 
 }
 
 static dma_addr_t
-gart_map_simple(struct device *dev, char *buf, size_t size, int dir)
+gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir)
 {
-       dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir);
+       dma_addr_t map = dma_map_area(dev, paddr, size, dir);
 
        flush_gart();
 
 
 /* Map a single area into the IOMMU */
 static dma_addr_t
-gart_map_single(struct device *dev, void *addr, size_t size, int dir)
+gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
 {
-       unsigned long phys_mem, bus;
+       unsigned long bus;
 
        if (!dev)
                dev = &fallback_dev;
 
-       phys_mem = virt_to_phys(addr);
-       if (!need_iommu(dev, phys_mem, size))
-               return phys_mem;
+       if (!need_iommu(dev, paddr, size))
+               return paddr;
 
-       bus = gart_map_simple(dev, addr, size, dir);
+       bus = gart_map_simple(dev, paddr, size, dir);
 
        return bus;
 }
 
 }
 
 static dma_addr_t
-nommu_map_single(struct device *hwdev, void *ptr, size_t size,
+nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size,
               int direction)
 {
-       dma_addr_t bus = virt_to_bus(ptr);
+       dma_addr_t bus = paddr;
        if (!check_addr("map_single", hwdev, bus, size))
                                return bad_dma_address;
        return bus;
 
 
 int swiotlb __read_mostly;
 
+static dma_addr_t
+swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size,
+                       int direction)
+{
+       return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction);
+}
+
 const struct dma_mapping_ops swiotlb_dma_ops = {
        .mapping_error = swiotlb_dma_mapping_error,
        .alloc_coherent = swiotlb_alloc_coherent,
        .free_coherent = swiotlb_free_coherent,
-       .map_single = swiotlb_map_single,
+       .map_single = swiotlb_map_single_phys,
        .unmap_single = swiotlb_unmap_single,
        .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
        .sync_single_for_device = swiotlb_sync_single_for_device,
 
                                dma_addr_t *dma_handle, gfp_t gfp);
        void            (*free_coherent)(struct device *dev, size_t size,
                                void *vaddr, dma_addr_t dma_handle);
-       dma_addr_t      (*map_single)(struct device *hwdev, void *ptr,
+       dma_addr_t      (*map_single)(struct device *hwdev, phys_addr_t ptr,
                                size_t size, int direction);
        /* like map_single, but doesn't check the device mask */
-       dma_addr_t      (*map_simple)(struct device *hwdev, char *ptr,
+       dma_addr_t      (*map_simple)(struct device *hwdev, phys_addr_t ptr,
                                size_t size, int direction);
        void            (*unmap_single)(struct device *dev, dma_addr_t addr,
                                size_t size, int direction);
               int direction)
 {
        BUG_ON(!valid_dma_direction(direction));
-       return dma_ops->map_single(hwdev, ptr, size, direction);
+       return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
 }
 
 static inline void
                                      size_t offset, size_t size,
                                      int direction)
 {
-       return dma_map_single(dev, page_address(page)+offset, size, direction);
+       BUG_ON(!valid_dma_direction(direction));
+       return dma_ops->map_single(dev, page_to_phys(page)+offset,
+                                  size, direction);
 }
 
 static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,