On Thu, 4 Mar 2010, Albert Herranz wrote: > 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). Now you've got it. Exactly right. > 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 Yes. > Can we then get rid of the transfer_dma != ~0 check? It seems useless now. No; that's how we detect the case where a driver has called usb_buffer_alloc() but the controller uses PIO. This whole coherent-buffer interface should have been designed differently from the start. usb_buffer_alloc() should return some sort of indicator telling drivers whether or not they are allowed to set URB_NO_TRANSFER_DMA_MAP. As it is, drivers assume they are always allowed to use that flag even though sometimes they shouldn't. 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