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:
>> Why exactly is this a little fragile?
> 
> Because it relies on people in the future understanding the reason for 
> this strange manipulation and not messing it up.  Yes, it will work, 
> but I'd prefer to do it differently.
> 
>> Doing the reset of {transfer,setup}_dma on unmap time has benefits from doing it on map time.
> 
> Maybe, but that's not what I was proposing.  I didn't say transfer_dma 
> should be reset at map time; I said that the submission test should be 
> changed.
> 

Ok, I didn't understand you.

>> In this case we will have a different transfer_dma value visible for the USB driver depending on if we are doing the first transfer of the URB after its allocation or a subsequent transfer.
>> Also it is hard (and may fail to do it right) for the USB stack to determine for the subsequent transfers if the transfer_dma value is then a real mapping or not.
> 
> The test shouldn't be too hard: If URB_NO_TRANSFER_DMA_MAP is set and
> the hcd uses DMA (or the DMA address isn't ~0) and HCD_NO_COHERENT_MEM
> isn't set, then the mapping is already okay.
> 

This isn't enough.

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 (true) do nothing
	transfer gets mapped
	transfer_dma becomes != ~0 during the mapping
	transfer_dma is not reset during the unmapping

/* 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 (true) do nothing
	transfer _doesn't_ get mapped, buffer is not sync'ed, transfer silently fails
	transfer_dma != ~0


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

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

> Alan Stern
> 

Thanks,
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