Alan Stern wrote:
> 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).
> 

Well, I was talking about our particular case here. I did not imply that we 
should forget about the other cases.

>> 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.
> 

When I said "do the mapping" there I meant to do a dma_map_single() if 
self.uses_dma, else if HCD_LOCAL_MEM is set then do a hcd_alloc_coherent().
I should have been more clear on that.

>>      - 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.
> 

I see. This case would include the PIO case too (for which dma_handle is set to 
all 1s).

So this assumes that transfer_dma should be set initially to 0 when allocating 
USB buffers for HCD_NO_COHERENT_MEM.

> 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.
> 

Good point.

> Alan Stern
> 

Thanks for your comments,
Albert

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to