Re: [RFC PATCH v3 2/2] USB: add HCD_NO_COHERENT_MEM host controller driver flag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Alan Stern wrote:
> On Thu, 4 Mar 2010, Albert Herranz wrote:
> Reread what I wrote above: If HCD_NO_COHERENT_MEM _isn't_ set!  With
> the correct test this becomes:
> 
> 	if URB_NO_TRANSFER_DMA_MAP is set (true) and transfer_dma != ~0 (true) and HCD_NO_COHERENT_MEM isn't set (false) do nothing
> 	transfer gets mapped again and works properly
> 

Sorry, I read you wrong again. I'm a bit thick today :)

So the map logic would be like this?

	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 != ~0 and HCD_NO_COHERENT_MEM is not set
		(this avoids your HCD_NO_COHERENT_MEM case) then do nothing.

	Otherwise if hcd->self.uses_dma is set then call dma_map_single
	Otherwise if HCD_LOCAL_MEM is set then call hcd_alloc_coherent
	Otherwise do nothing (PIO case).

Then we have:

(HCD_NO_COHERENT_MEM):

	usb_buffer_alloc()
	/* urb->transfer_dma == ~0 */
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	/* 1st transfer */
	usb_submit_urb(urb, GFP_KERNEL);
		if URB_NO_TRANSFER_DMA_MAP is set (true) and transfer_dma != ~0 (false) and HCD_NO_COHERENT_MEM not set (false) do nothing
		transfer gets mapped, Ok
	/* urb->transfer_dma != ~0 */

	/* 2nd transfer */
	usb_submit_urb(urb, GFP_KERNEL);
		if URB_NO_TRANSFER_DMA_MAP is set (true) and transfer_dma != ~0 (true) and HCD_NO_COHERENT_MEM not set (false) do nothing
		transfer gets mapped, Ok

(!HCD_NO_COHERENT_MEM):

	usb_buffer_alloc()
	/* urb->transfer_dma != ~0 */
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	/* 1st transfer */
	usb_submit_urb(urb, GFP_KERNEL);
		if URB_NO_TRANSFER_DMA_MAP is set (true) and transfer_dma != ~0 (true) and HCD_NO_COHERENT_MEM not set (true) do nothing
		transfer doesn't get mapped, Ok

	/* 2nd transfer */
	usb_submit_urb(urb, GFP_KERNEL);
		if URB_NO_TRANSFER_DMA_MAP is set (true) and transfer_dma != ~0 (true) and HCD_NO_COHERENT_MEM not set (true) do nothing
		transfer doesn't get mapped, Ok

Can we then get rid of the transfer_dma != ~0 check? It seems useless now.

>>> You're concerned that transfer_dma might contain a valid DMA address
>>> for an existing mapping.  How could it?  usb_buffer_alloc() won't
>>> return a valid address if HCD_NO_COHERENT_MEM is set.  And even if it
>>> did, you would overwrite that valid address at unmap time anyway.
>>>
>> transfer_dma gets a valid mapping when it is mapped by dma_map_single() at map time.
> 
> That address is no longer valid after the transfer buffer gets unmapped
> by dma_unmap_single() at unmap time.
> 

Yes and no.
Yes, if you consider the real map/unmap that happens behind the scenes.
No, if you look at what the USB driver thinks it's happening.
The USB driver thinks that it got a "coherent" buffer from usb_alloc_buffer() and assumes that urb->transfer_dma is preserved because the USB stack is supposed to not touch that when URB_NO_TRANSFER_DMA_MAP.

But, anyway, this shouldn't cause a real problem, I guess.

>> In the scenario I propose, if the transfer buffer wasn't mapped then it won't get unmapped (the new flags control that), and thus transfer_dma won't be touched.
>> The only case it will be overwritten to ~0 at unmap time is when transfer_dma was ~0 at map time _and_ it was actually mapped (HCD_NO_COHERENT_MEM case).
> 
> It's better to have all the tricky computations in one place: map time.
> Don't split them up into two places.
> 

Ok, I'll cook a patch with your approach.

> Alan Stern
> 

Thanks again,
Albert


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux