diff options
| -rw-r--r-- | drivers/firewire/ohci.c | 35 |
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) | |||
| 750 | */ | 750 | */ |
| 751 | 751 | ||
| 752 | offset = offsetof(struct ar_buffer, data); | 752 | offset = offsetof(struct ar_buffer, data); |
| 753 | start = buffer = ab; | 753 | start = ab; |
| 754 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; | 754 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; |
| 755 | buffer = ab->data; | ||
| 755 | 756 | ||
| 756 | ab = ab->next; | 757 | ab = ab->next; |
| 757 | d = &ab->descriptor; | 758 | d = &ab->descriptor; |
| 758 | size = buffer + PAGE_SIZE - ctx->pointer; | 759 | size = start + PAGE_SIZE - ctx->pointer; |
| 759 | /* valid buffer data in the next page */ | 760 | /* valid buffer data in the next page */ |
| 760 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); | 761 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); |
| 761 | /* what actually fits in this page */ | 762 | /* what actually fits in this page */ |
| 762 | size2 = min(rest, (size_t)PAGE_SIZE - size); | 763 | size2 = min(rest, (size_t)PAGE_SIZE - offset - size); |
| 763 | memmove(buffer, ctx->pointer, size); | 764 | memmove(buffer, ctx->pointer, size); |
| 764 | memcpy(buffer + size, ab->data, size2); | 765 | memcpy(buffer + size, ab->data, size2); |
| 765 | ctx->current_buffer = ab; | ||
| 766 | ctx->pointer = (void *) ab->data + rest; | ||
| 767 | 766 | ||
| 768 | while (size > 0) { | 767 | while (size > 0) { |
| 769 | void *next = handle_ar_packet(ctx, buffer); | 768 | void *next = handle_ar_packet(ctx, buffer); |
| @@ -782,22 +781,30 @@ static void ar_context_tasklet(unsigned long data) | |||
| 782 | size -= pktsize; | 781 | size -= pktsize; |
| 783 | /* fill up this page again */ | 782 | /* fill up this page again */ |
| 784 | size3 = min(rest - size2, | 783 | size3 = min(rest - size2, |
| 785 | (size_t)PAGE_SIZE - size - size2); | 784 | (size_t)PAGE_SIZE - offset - size - size2); |
| 786 | memcpy(buffer + size + size2, | 785 | memcpy(buffer + size + size2, |
| 787 | (void *) ab->data + size2, size3); | 786 | (void *) ab->data + size2, size3); |
| 788 | size2 += size3; | 787 | size2 += size3; |
| 789 | } | 788 | } |
| 790 | 789 | ||
| 791 | /* handle the packets that are fully in the next page */ | 790 | if (rest > 0) { |
| 792 | buffer = (void *) ab->data + (buffer - (start + size)); | 791 | /* handle the packets that are fully in the next page */ |
| 793 | end = (void *) ab->data + rest; | 792 | buffer = (void *) ab->data + |
| 793 | (buffer - (start + offset + size)); | ||
| 794 | end = (void *) ab->data + rest; | ||
| 794 | 795 | ||
| 795 | while (buffer < end) | 796 | while (buffer < end) |
| 796 | buffer = handle_ar_packet(ctx, buffer); | 797 | buffer = handle_ar_packet(ctx, buffer); |
| 798 | |||
| 799 | ctx->current_buffer = ab; | ||
| 800 | ctx->pointer = end; | ||
| 797 | 801 | ||
| 798 | dma_free_coherent(ohci->card.device, PAGE_SIZE, | 802 | dma_free_coherent(ohci->card.device, PAGE_SIZE, |
| 799 | start, start_bus); | 803 | start, start_bus); |
| 800 | ar_context_add_page(ctx); | 804 | ar_context_add_page(ctx); |
| 805 | } else { | ||
| 806 | ctx->pointer = start + PAGE_SIZE; | ||
| 807 | } | ||
| 801 | } else { | 808 | } else { |
| 802 | buffer = ctx->pointer; | 809 | buffer = ctx->pointer; |
| 803 | ctx->pointer = end = | 810 | ctx->pointer = end = |
