2010/8/31 Martin Fuzzey <mfuzzey@xxxxxxxxx>: > If these are not met use a bounce buffer. > > This is done by adding a member dma_align_shift to > struct hc_driver. Defaulting to zero causes unmodified > HCDs to be assumed to be byte aligned DMA capable. > > Signed-off-by: Martin Fuzzey <mfuzzey@xxxxxxxxx> > > --- > > drivers/usb/core/hcd.c | 54 +++++++++++++++++++++++++++++++++++++---------- > include/linux/usb.h | 1 + > include/linux/usb/hcd.h | 2 ++ > 3 files changed, 45 insertions(+), 12 deletions(-) > > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > index 12742f1..8ad9367 100644 > --- a/drivers/usb/core/hcd.c > +++ b/drivers/usb/core/hcd.c > @@ -1286,12 +1286,19 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) > urb->transfer_dma, > urb->transfer_buffer_length, > dir); > - else if (urb->transfer_flags & URB_DMA_MAP_SINGLE) > + else if (urb->transfer_flags & URB_DMA_MAP_SINGLE) { > dma_unmap_single(hcd->self.controller, > urb->transfer_dma, > urb->transfer_buffer_length, > dir); > - else if (urb->transfer_flags & URB_MAP_LOCAL) > + if (urb->bounce_buffer) { > + if (dir == DMA_FROM_DEVICE) > + memcpy(urb->transfer_buffer, > + urb->bounce_buffer, > + urb->transfer_buffer_length); > + kfree(urb->bounce_buffer); dma_unmap_single is needed for bounce_buffer. > + } > + } else if (urb->transfer_flags & URB_MAP_LOCAL) > hcd_free_coherent(urb->dev->bus, > &urb->transfer_dma, > &urb->transfer_buffer, > @@ -1373,16 +1380,39 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, > else > urb->transfer_flags |= URB_DMA_MAP_PAGE; > } else { > - urb->transfer_dma = dma_map_single( > - hcd->self.controller, > - urb->transfer_buffer, > - urb->transfer_buffer_length, > - dir); > - if (dma_mapping_error(hcd->self.controller, > - urb->transfer_dma)) > - ret = -EAGAIN; > - else > - urb->transfer_flags |= URB_DMA_MAP_SINGLE; > + void *buffer = urb->transfer_buffer; > + > + if (IS_ALIGNED((unsigned long)buffer, > + 1 << hcd->driver->dma_align_shift)) > + urb->bounce_buffer = NULL; Suppose hcd->driver->dma_align_shift is zero and HC is byte aligned DMA enabled, this means DMA is doable between byte aligned memory and HC, but this does __not__ mean it is safe to do dma mapping or unmapping between CPU and byte aligned memory, which may cause sync issues between memory and CPU cache. So seems the idea behind the patch is not correct, IMHO. -- Lei Ming -- 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