On Thu, 4 Mar 2010, Albert Herranz wrote: > > 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 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 > > 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. > 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. Alan Stern -- 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