From: Albert H. <he...@us...> - 2009-12-09 18:40:17
|
Update of /cvsroot/gc-linux/linux/arch/powerpc/include/asm In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv21229/arch/powerpc/include/asm Modified Files: dma-mapping.h Log Message: Forward to v2.6.32. Index: dma-mapping.h =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/powerpc/include/asm/dma-mapping.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** dma-mapping.h 9 Dec 2009 18:18:06 -0000 1.6 --- dma-mapping.h 9 Dec 2009 18:40:09 -0000 1.7 *************** *** 15,18 **** --- 15,19 ---- #include <linux/scatterlist.h> #include <linux/dma-attrs.h> + #include <linux/dma-debug.h> #include <asm/io.h> #include <asm/swiotlb.h> *************** *** 26,30 **** void *vaddr, dma_addr_t dma_handle); - extern unsigned long get_dma_direct_offset(struct device *dev); #ifdef CONFIG_NOT_COHERENT_CACHE --- 27,30 ---- *************** *** 65,120 **** /* - * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO - */ - struct dma_mapping_ops { - void * (*alloc_coherent)(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag); - void (*free_coherent)(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle); - int (*map_sg)(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - struct dma_attrs *attrs); - void (*unmap_sg)(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - struct dma_attrs *attrs); - int (*dma_supported)(struct device *dev, u64 mask); - int (*set_dma_mask)(struct device *dev, u64 dma_mask); - dma_addr_t (*map_page)(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs); - void (*unmap_page)(struct device *dev, - dma_addr_t dma_address, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs); - int (*addr_needs_map)(struct device *dev, dma_addr_t addr, - size_t size); - #ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS - void (*sync_single_range_for_cpu)(struct device *hwdev, - dma_addr_t dma_handle, unsigned long offset, - size_t size, - enum dma_data_direction direction); - void (*sync_single_range_for_device)(struct device *hwdev, - dma_addr_t dma_handle, unsigned long offset, - size_t size, - enum dma_data_direction direction); - void (*sync_sg_for_cpu)(struct device *hwdev, - struct scatterlist *sg, int nelems, - enum dma_data_direction direction); - void (*sync_sg_for_device)(struct device *hwdev, - struct scatterlist *sg, int nelems, - enum dma_data_direction direction); - #endif - }; - - /* * Available generic sets of operations */ #ifdef CONFIG_PPC64 ! extern struct dma_mapping_ops dma_iommu_ops; #endif ! extern struct dma_mapping_ops dma_direct_ops; ! static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) { /* We don't handle the NULL dev case for ISA for now. We could --- 65,76 ---- /* * Available generic sets of operations */ #ifdef CONFIG_PPC64 ! extern struct dma_map_ops dma_iommu_ops; #endif ! extern struct dma_map_ops dma_direct_ops; ! static inline struct dma_map_ops *get_dma_ops(struct device *dev) { /* We don't handle the NULL dev case for ISA for now. We could *************** *** 129,140 **** } ! static inline void set_dma_ops(struct device *dev, struct dma_mapping_ops *ops) { dev->archdata.dma_ops = ops; } static inline int dma_supported(struct device *dev, u64 mask) { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); if (unlikely(dma_ops == NULL)) --- 85,123 ---- } ! static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) { dev->archdata.dma_ops = ops; } + /* + * get_dma_offset() + * + * Get the dma offset on configurations where the dma address can be determined + * from the physical address by looking at a simple offset. Direct dma and + * swiotlb use this function, but it is typically not used by implementations + * with an iommu. + */ + static inline dma_addr_t get_dma_offset(struct device *dev) + { + if (dev) + return dev->archdata.dma_data.dma_offset; + + return PCI_DRAM_OFFSET; + } + + static inline void set_dma_offset(struct device *dev, dma_addr_t off) + { + if (dev) + dev->archdata.dma_data.dma_offset = off; + } + + /* this will be removed soon */ + #define flush_write_buffers() + + #include <asm-generic/dma-mapping-common.h> + static inline int dma_supported(struct device *dev, u64 mask) { ! struct dma_map_ops *dma_ops = get_dma_ops(dev); if (unlikely(dma_ops == NULL)) *************** *** 150,154 **** static inline int dma_set_mask(struct device *dev, u64 dma_mask) { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); if (unlikely(dma_ops == NULL)) --- 133,137 ---- static inline int dma_set_mask(struct device *dev, u64 dma_mask) { ! struct dma_map_ops *dma_ops = get_dma_ops(dev); if (unlikely(dma_ops == NULL)) *************** *** 162,426 **** } - /* - * map_/unmap_single actually call through to map/unmap_page now that all the - * dma_mapping_ops have been converted over. We just have to get the page and - * offset to pass through to map_page - */ - static inline dma_addr_t dma_map_single_attrs(struct device *dev, - void *cpu_addr, - size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) - { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - return dma_ops->map_page(dev, virt_to_page(cpu_addr), - (unsigned long)cpu_addr % PAGE_SIZE, size, - direction, attrs); - } - - static inline void dma_unmap_single_attrs(struct device *dev, - dma_addr_t dma_addr, - size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) - { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - dma_ops->unmap_page(dev, dma_addr, size, direction, attrs); - } - - static inline dma_addr_t dma_map_page_attrs(struct device *dev, - struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) - { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - return dma_ops->map_page(dev, page, offset, size, direction, attrs); - } - - static inline void dma_unmap_page_attrs(struct device *dev, - dma_addr_t dma_address, - size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) - { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - dma_ops->unmap_page(dev, dma_address, size, direction, attrs); - } - - static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - struct dma_attrs *attrs) - { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - return dma_ops->map_sg(dev, sg, nents, direction, attrs); - } - - static inline void dma_unmap_sg_attrs(struct device *dev, - struct scatterlist *sg, - int nhwentries, - enum dma_data_direction direction, - struct dma_attrs *attrs) - { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs); - } - static inline void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); ! ! BUG_ON(!dma_ops); ! return dma_ops->alloc_coherent(dev, size, dma_handle, flag); ! } ! ! static inline void dma_free_coherent(struct device *dev, size_t size, ! void *cpu_addr, dma_addr_t dma_handle) ! { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); ! ! BUG_ON(!dma_ops); ! dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); ! } ! ! static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, ! size_t size, ! enum dma_data_direction direction) ! { ! return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL); ! } ! ! static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, ! size_t size, ! enum dma_data_direction direction) ! { ! dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL); ! } ! ! static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, ! unsigned long offset, size_t size, ! enum dma_data_direction direction) ! { ! return dma_map_page_attrs(dev, page, offset, size, direction, NULL); ! } ! ! static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, ! size_t size, ! enum dma_data_direction direction) ! { ! dma_unmap_page_attrs(dev, dma_address, size, direction, NULL); ! } ! ! static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, ! int nents, enum dma_data_direction direction) ! { ! return dma_map_sg_attrs(dev, sg, nents, direction, NULL); ! } ! ! static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, ! int nhwentries, ! enum dma_data_direction direction) ! { ! dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL); ! } ! ! #ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS ! static inline void dma_sync_single_for_cpu(struct device *dev, ! dma_addr_t dma_handle, size_t size, ! enum dma_data_direction direction) ! { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); ! ! BUG_ON(!dma_ops); ! ! if (dma_ops->sync_single_range_for_cpu) ! dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, ! size, direction); ! } ! ! static inline void dma_sync_single_for_device(struct device *dev, ! dma_addr_t dma_handle, size_t size, ! enum dma_data_direction direction) ! { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); ! if (dma_ops->sync_single_range_for_device) ! dma_ops->sync_single_range_for_device(dev, dma_handle, ! 0, size, direction); ! } ! ! static inline void dma_sync_sg_for_cpu(struct device *dev, ! struct scatterlist *sgl, int nents, ! enum dma_data_direction direction) ! { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); ! BUG_ON(!dma_ops); ! if (dma_ops->sync_sg_for_cpu) ! dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); } ! static inline void dma_sync_sg_for_device(struct device *dev, ! struct scatterlist *sgl, int nents, ! enum dma_data_direction direction) { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); ! if (dma_ops->sync_sg_for_device) ! dma_ops->sync_sg_for_device(dev, sgl, nents, direction); ! } ! ! static inline void dma_sync_single_range_for_cpu(struct device *dev, ! dma_addr_t dma_handle, unsigned long offset, size_t size, ! enum dma_data_direction direction) ! { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); ! ! BUG_ON(!dma_ops); ! if (dma_ops->sync_single_range_for_cpu) ! dma_ops->sync_single_range_for_cpu(dev, dma_handle, ! offset, size, direction); } ! static inline void dma_sync_single_range_for_device(struct device *dev, ! dma_addr_t dma_handle, unsigned long offset, size_t size, ! enum dma_data_direction direction) { ! struct dma_mapping_ops *dma_ops = get_dma_ops(dev); ! BUG_ON(!dma_ops); ! if (dma_ops->sync_single_range_for_device) ! dma_ops->sync_single_range_for_device(dev, dma_handle, offset, ! size, direction); ! } ! #else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */ ! static inline void dma_sync_single_for_cpu(struct device *dev, ! dma_addr_t dma_handle, size_t size, ! enum dma_data_direction direction) ! { } ! static inline void dma_sync_single_for_device(struct device *dev, ! dma_addr_t dma_handle, size_t size, ! enum dma_data_direction direction) { ! } ! static inline void dma_sync_sg_for_cpu(struct device *dev, ! struct scatterlist *sgl, int nents, ! enum dma_data_direction direction) ! { ! } ! static inline void dma_sync_sg_for_device(struct device *dev, ! struct scatterlist *sgl, int nents, ! enum dma_data_direction direction) ! { ! } ! static inline void dma_sync_single_range_for_cpu(struct device *dev, ! dma_addr_t dma_handle, unsigned long offset, size_t size, ! enum dma_data_direction direction) ! { } ! static inline void dma_sync_single_range_for_device(struct device *dev, ! dma_addr_t dma_handle, unsigned long offset, size_t size, ! enum dma_data_direction direction) { } - #endif ! static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { ! #ifdef CONFIG_PPC64 ! return (dma_addr == DMA_ERROR_CODE); ! #else ! return 0; ! #endif } --- 145,212 ---- } static inline void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { ! struct dma_map_ops *dma_ops = get_dma_ops(dev); ! void *cpu_addr; BUG_ON(!dma_ops); ! cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag); ! debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); ! return cpu_addr; } ! static inline void dma_free_coherent(struct device *dev, size_t size, ! void *cpu_addr, dma_addr_t dma_handle) { ! struct dma_map_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); ! debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); ! dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); } ! static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { ! struct dma_map_ops *dma_ops = get_dma_ops(dev); ! if (dma_ops->mapping_error) ! return dma_ops->mapping_error(dev, dma_addr); ! #ifdef CONFIG_PPC64 ! return (dma_addr == DMA_ERROR_CODE); ! #else ! return 0; ! #endif } ! static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) { ! #ifdef CONFIG_SWIOTLB ! struct dev_archdata *sd = &dev->archdata; ! if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr) ! return 0; ! #endif ! if (!dev->dma_mask) ! return 0; ! return addr + size <= *dev->dma_mask; } ! static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { + return paddr + get_dma_offset(dev); } ! static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { ! return daddr - get_dma_offset(dev); } |