Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 303540
b: refs/heads/master
c: fe37577
h: refs/heads/master
v: v3
  • Loading branch information
Venu Byravarasu authored and Greg Kroah-Hartman committed Apr 18, 2012
1 parent 0a26241 commit 24ffcb4
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 259b83a387dfb275988e72e25e3dd9e62d4916ac
refs/heads/master: fe375774bd88a358d24c3f624373117c642f6999
35 changes: 14 additions & 21 deletions trunk/drivers/usb/host/ehci-tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,26 +462,23 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
}
#endif

struct temp_buffer {
struct dma_aligned_buffer {
void *kmalloc_ptr;
void *old_xfer_buffer;
u8 data[0];
};

static void free_temp_buffer(struct urb *urb)
static void free_dma_aligned_buffer(struct urb *urb)
{
enum dma_data_direction dir;
struct temp_buffer *temp;
struct dma_aligned_buffer *temp;

if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
return;

dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
temp = container_of(urb->transfer_buffer,
struct dma_aligned_buffer, data);

temp = container_of(urb->transfer_buffer, struct temp_buffer,
data);

if (dir == DMA_FROM_DEVICE)
if (usb_urb_dir_in(urb))
memcpy(temp->old_xfer_buffer, temp->data,
urb->transfer_buffer_length);
urb->transfer_buffer = temp->old_xfer_buffer;
Expand All @@ -490,33 +487,29 @@ static void free_temp_buffer(struct urb *urb)
urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
}

static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
static int alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
{
enum dma_data_direction dir;
struct temp_buffer *temp, *kmalloc_ptr;
struct dma_aligned_buffer *temp, *kmalloc_ptr;
size_t kmalloc_size;

if (urb->num_sgs || urb->sg ||
urb->transfer_buffer_length == 0 ||
!((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1)))
return 0;

dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;

/* Allocate a buffer with enough padding for alignment */
kmalloc_size = urb->transfer_buffer_length +
sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1;
sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1;

kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
if (!kmalloc_ptr)
return -ENOMEM;

/* Position our struct temp_buffer such that data is aligned */
/* Position our struct dma_aligned_buffer such that data is aligned */
temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1;

temp->kmalloc_ptr = kmalloc_ptr;
temp->old_xfer_buffer = urb->transfer_buffer;
if (dir == DMA_TO_DEVICE)
if (usb_urb_dir_out(urb))
memcpy(temp->data, urb->transfer_buffer,
urb->transfer_buffer_length);
urb->transfer_buffer = temp->data;
Expand All @@ -531,21 +524,21 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
{
int ret;

ret = alloc_temp_buffer(urb, mem_flags);
ret = alloc_dma_aligned_buffer(urb, mem_flags);
if (ret)
return ret;

ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
if (ret)
free_temp_buffer(urb);
free_dma_aligned_buffer(urb);

return ret;
}

static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
{
usb_hcd_unmap_urb_for_dma(hcd, urb);
free_temp_buffer(urb);
free_dma_aligned_buffer(urb);
}

static const struct hc_driver tegra_ehci_hc_driver = {
Expand Down

0 comments on commit 24ffcb4

Please sign in to comment.