[RFC] POWERPC: Merge 32 and 64-bit dma code
Becky Bruce
becky.bruce at freescale.com
Wed Jun 4 10:10:51 EST 2008
On May 23, 2008, at 4:51 AM, Christoph Hellwig wrote:
> On Wed, Apr 30, 2008 at 06:36:43PM -0500, Becky Bruce wrote:
>> In addition, the dma_map/unmap_page functions are added to dma_ops on
>> HIGHMEM-enabled configs because we can't just fall back on map/
>> unmap_single
>> when HIGHMEM is enabled. Adding these to dma_ops makes it cleaner to
>> substitute different functionality once we have iommu/swiotlb
>> support.
>
> Maybe I'm missing something but we should only have the page ones.
> virt_to_page is cheap and we'll most likely need the phys address
> which
> we get from the page anyway.
Thanks for taking the time to review this! My apologies for the slow
response - I just returned from a couple of weeks of being off-line
on vacation.
If I understand your comment correctly, you're asking me to drop map/
unmap_single from the dma_ops, and change dma_map_single() to do
virt_to_page() on the address, and then call dma_ops->map_page()?
I'll look into doing that. It sounds like it might be cleaner.
>> There will be other patches that precede this one - I plan to
>> duplicate
>> dma_mapping.h into include/asm-ppc to avoid breakage there. There
>> will
>> also be a patch to rename dma_64.c to dma.c, and a series of
>> patches to
>> modify drivers that pass NULL dev pointers.
>
> Note that NULL dev pointers are fine for the pci_ API and we need to
> handle those. But if you're talking about NULL dev pointers to the
> dma_
> API yes, those should be fixed.
I was talking about the DMA API, but I will double-check that I
haven't overlooked something here.
>
>> + udbg.o misc.o io.o dma_64.o\
>
> Whitespace before the \ please.
Will fix....
>
>> +#ifdef CONFIG_PPC64
>> +#include <asm/iommu.h>
>> +
>> /*
>> * Generic iommu implementation
>> */
>> @@ -108,6 +110,8 @@ struct dma_mapping_ops dma_iommu_ops = {
>> .dma_supported = dma_iommu_dma_supported,
>> };
>> EXPORT_SYMBOL(dma_iommu_ops);
>> +#endif /* CONFIG_PPC64 */
>
> This should probably be split into a dma_iommu.c file
I'm happy to do that, unless any of the 64B guys have some objection.
>
>> +#ifndef CONFIG_NOT_COHERENT_CACHE
>> static void *dma_direct_alloc_coherent(struct device *dev, size_t
>> size,
>> dma_addr_t *dma_handle, gfp_t flag)
>> {
> The alloc_coherent ops probably should go into a dma-coherent.c file
Agreed.
>
>> - struct page *page;
>> void *ret;
>> - int node = dev->archdata.numa_node;
>> + struct page *page;
>> + int node = -1;
>> +#ifdef CONFIG_PPC64
>> + node = dev->archdata.numa_node;
>> +#else
>
> Please convert 64bit powerpc to use the numa_node field directly in
> struct device and use the dev_to_node accessor. That way it does
> the right thing and we save a field per struct device instance.
I'm also happy to do that (and your next couple of suggestions) if
it's OK with the 64b folks I was trying to mess with the 64B code as
little as possible, since I have no means of testing it.
>
>
>> + /* ignore region specifiers */
>> + flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
>> +
>> + /* Bust slacker drivers that pass a NULL dev ptr */
>> + BUG_ON(dev == NULL);
>
> These should be done for 64bit, too.
>
>> + if (dev->coherent_dma_mask < 0xffffffff)
>> + flag |= GFP_DMA;
>
> This one probably aswell.
>
>> +#else /* CONFIG_NOT_COHERENT_CACHE */
>> +
>> +static void *dma_direct_alloc_noncoherent(struct device *dev,
>> size_t size,
>> + dma_addr_t *dma_handle, gfp_t flag)
>> +{
>> + return __dma_alloc_coherent(size, dma_handle, flag);
>> +}
>> +
>> +static void dma_direct_free_noncoherent(struct device *dev,
>> size_t size,
>> + void *vaddr, dma_addr_t dma_handle)
>> +{
>> + __dma_free_coherent(size, vaddr);
>> +}
>> +#endif /* CONFIG_NOT_COHERENT_CACHE */
>
> Should probably go into dma-noncoherent.c
Right-o.
>
>> @@ -180,20 +215,59 @@ static void dma_direct_unmap_sg(struct
>> device *dev, struct scatterlist *sg,
>>
>> static int dma_direct_dma_supported(struct device *dev, u64 mask)
>> {
>> +#ifdef CONFIG_PPC64
>> /* Could be improved to check for memory though it better be
>> * done via some global so platforms can set the limit in case
>> * they have limited DMA windows
>> */
>> return mask >= DMA_32BIT_MASK;
>> +#else
>> + return 1;
>> +#endif
>
> I think this depends on the dma ops and thus should be turned into
> one.
dma_supported *is* part of dma_ops. Am I misunderstanding your comment?
Thanks! I hope to have an updated version out in week or two - I'm
in the middle of debugging the conglomeration of this patch, swiotlb,
and 36-bit physical addressing support on 32bit powerpc right now,
but as soon as I have that marginally working, I'm going to start
cleaning up the pieces and pushing them out to get more eyeballs on
them.
-Becky
More information about the Linuxppc-dev
mailing list