On Mon, 1 Mar 2010, Albert Herranz wrote:
> >> Am I on the right path?
> >
> > More or less. I would do it somewhat differently:
> >
> > If URB_NO_TRANSFER_DMA_MAP is set then no map is needed.
> > Otherwise if num_sgs > 0 then no map is needed.
> > Otherwise if HCD_NO_COHERENT_MEM is set then use
> > hcd_alloc_coherent().
> > Otherwise if transfer_buffer_length > 0 then use
> > dma_map_single().
> >
>
> I think that logic is not quite right.
> Remember that the final goal is to avoid allocating USB buffers from coherent
> memory (because the USB drivers access USB buffers without access
> restrictions but the platform I'm working on can't write to coherent memory
> unless it is done in 32-bit chunks).
Actually the final goal is to make the mapping/unmapping algorithms
clear and correct. One of the subgoals involves avoiding coherent USB
buffers, but there are others as well (if you look back the through the
linux-usb mailing list for the last few weeks you'll see a discussion
about a controller which has to use PIO for control transfers but can
use DMA for other types).
> And we want to avoid bouncing at the USB layer too (that's what v1 did).
>
> The strategy so far is:
> - we have modified the USB buffer allocation routines
> hcd_buffer_alloc()/hcd_buffer_free() to always return normal kernel memory
> when HCD_NO_COHERENT_MEM is set on the host controller.
> - during map_urb_for_dma()/unmap_urb_for_dma() we need to make sure that
> those USB buffers are sync'ed, even if we are told
> USB_NO_{SETUP,TRANSFER}_DMA_MAP
>
> So the logic would be:
>
> If URB_NO_TRANSFER_DMA_MAP is _cleared_ then do the mapping
No, that's wrong because it ignores the HCD_LOCAL_MEM flag.
> - this case covers normal kernel memory used as a buffer and not
> already DMA mapped by a USB driver
>
> Otherwise if HCD_NO_COHERENT_MEM is set _and_ num_sgs == 0 _and_
> transfer_buffer_length > 0 then do the mapping too
> - this case covers USB buffers allocated via usb_buffer_alloc() and
> marked URB_NO_TRANSFER_DMA_MAP by a USB driver, which are allocated from
> normal kernel memory when HCD_NO_COHERENT_MEM is set (we avoid bouncing
> buffers here too, at least if they sit already within MEM2 in the Wii, but
> anyway that's part of the platform DMA mapping code)
>
> s-g urbs do not need a mapping as they have already been mapped, marked
> URB_NO_TRANSFER_DMA_MAP and have num_sgs > 0
Actually the test for transfer_buffer_length == 0 should be done first,
since obviously no mapping is needed if there's no data. (And in fact
the current code does do this; I was wrong earlier when I said it
doesn't.)
So let's make things a little easier by first testing the conditions
under which no mapping is needed:
If transfer_buffer_length is 0 then do nothing.
Otherwise if num_sgs > 0 then do nothing.
Otherwise if URB_NO_TRANSFER_DMA_MAP and transfer_dma
are both set (this avoids your HCD_NO_COHERENT_MEM
case) then do nothing.
The remaining cases all need mapping and/or bounce buffers:
Otherwise if HCD_LOCAL_MEM is set then call hcd_alloc_coherent.
Otherwise call dma_map_single.
Finally, the unmapping tests can be simplified greatly if the kind of
mapping is recorded in the URB flags.
Alan Stern
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://lists.ozlabs.org/listinfo/linuxppc-dev