Commit 837596a6 authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Stefan Richter

firewire: ohci: avoid reallocation of AR buffers

Freeing an AR buffer page just to allocate a new page immediately
afterwards is not only a pointless effort but also dangerous because
the allocation can fail, which would result in an oops later.

Split ar_context_add_page() into two functions so that we can reuse
the old page directly.
Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Tested-by: default avatarMaxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent a1f805e5
...@@ -577,17 +577,11 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, ...@@ -577,17 +577,11 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr,
return ret; return ret;
} }
static int ar_context_add_page(struct ar_context *ctx) static void ar_context_link_page(struct ar_context *ctx,
struct ar_buffer *ab, dma_addr_t ab_bus)
{ {
struct device *dev = ctx->ohci->card.device;
struct ar_buffer *ab;
dma_addr_t uninitialized_var(ab_bus);
size_t offset; size_t offset;
ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
if (ab == NULL)
return -ENOMEM;
ab->next = NULL; ab->next = NULL;
memset(&ab->descriptor, 0, sizeof(ab->descriptor)); memset(&ab->descriptor, 0, sizeof(ab->descriptor));
ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
...@@ -606,6 +600,19 @@ static int ar_context_add_page(struct ar_context *ctx) ...@@ -606,6 +600,19 @@ static int ar_context_add_page(struct ar_context *ctx)
reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
flush_writes(ctx->ohci); flush_writes(ctx->ohci);
}
static int ar_context_add_page(struct ar_context *ctx)
{
struct device *dev = ctx->ohci->card.device;
struct ar_buffer *ab;
dma_addr_t uninitialized_var(ab_bus);
ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
if (ab == NULL)
return -ENOMEM;
ar_context_link_page(ctx, ab, ab_bus);
return 0; return 0;
} }
...@@ -730,7 +737,6 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) ...@@ -730,7 +737,6 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
static void ar_context_tasklet(unsigned long data) static void ar_context_tasklet(unsigned long data)
{ {
struct ar_context *ctx = (struct ar_context *)data; struct ar_context *ctx = (struct ar_context *)data;
struct fw_ohci *ohci = ctx->ohci;
struct ar_buffer *ab; struct ar_buffer *ab;
struct descriptor *d; struct descriptor *d;
void *buffer, *end; void *buffer, *end;
...@@ -799,9 +805,7 @@ static void ar_context_tasklet(unsigned long data) ...@@ -799,9 +805,7 @@ static void ar_context_tasklet(unsigned long data)
ctx->current_buffer = ab; ctx->current_buffer = ab;
ctx->pointer = end; ctx->pointer = end;
dma_free_coherent(ohci->card.device, PAGE_SIZE, ar_context_link_page(ctx, start, start_bus);
start, start_bus);
ar_context_add_page(ctx);
} else { } else {
ctx->pointer = start + PAGE_SIZE; ctx->pointer = start + PAGE_SIZE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment