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 = |