summaryrefslogtreecommitdiff
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 5826ae333b19..7570b71a2453 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -750,20 +750,19 @@ static void ar_context_tasklet(unsigned long data)
*/
offset = offsetof(struct ar_buffer, data);
- start = buffer = ab;
+ start = ab;
start_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
+ buffer = ab->data;
ab = ab->next;
d = &ab->descriptor;
- size = buffer + PAGE_SIZE - ctx->pointer;
+ size = start + PAGE_SIZE - ctx->pointer;
/* valid buffer data in the next page */
rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count);
/* what actually fits in this page */
- size2 = min(rest, (size_t)PAGE_SIZE - size);
+ size2 = min(rest, (size_t)PAGE_SIZE - offset - size);
memmove(buffer, ctx->pointer, size);
memcpy(buffer + size, ab->data, size2);
- ctx->current_buffer = ab;
- ctx->pointer = (void *) ab->data + rest;
while (size > 0) {
void *next = handle_ar_packet(ctx, buffer);
@@ -782,22 +781,30 @@ static void ar_context_tasklet(unsigned long data)
size -= pktsize;
/* fill up this page again */
size3 = min(rest - size2,
- (size_t)PAGE_SIZE - size - size2);
+ (size_t)PAGE_SIZE - offset - size - size2);
memcpy(buffer + size + size2,
(void *) ab->data + size2, size3);
size2 += size3;
}
- /* handle the packets that are fully in the next page */
- buffer = (void *) ab->data + (buffer - (start + size));
- end = (void *) ab->data + rest;
+ if (rest > 0) {
+ /* handle the packets that are fully in the next page */
+ buffer = (void *) ab->data +
+ (buffer - (start + offset + size));
+ end = (void *) ab->data + rest;
- while (buffer < end)
- buffer = handle_ar_packet(ctx, buffer);
+ while (buffer < end)
+ buffer = handle_ar_packet(ctx, buffer);
+
+ ctx->current_buffer = ab;
+ ctx->pointer = end;
- dma_free_coherent(ohci->card.device, PAGE_SIZE,
- start, start_bus);
- ar_context_add_page(ctx);
+ dma_free_coherent(ohci->card.device, PAGE_SIZE,
+ start, start_bus);
+ ar_context_add_page(ctx);
+ } else {
+ ctx->pointer = start + PAGE_SIZE;
+ }
} else {
buffer = ctx->pointer;
ctx->pointer = end =